#include <libecc/curves/aff_pt.h>
#define AFF_PT_MAGIC ((word_t)(0x4c82a9bcd0d9ffabULL))
int aff_pt_check_initialized(aff_pt_src_t in)
{
int ret;
MUST_HAVE(((in != NULL) && (in->magic == AFF_PT_MAGIC)), ret, err);
ret = ec_shortw_crv_check_initialized(in->crv);
err:
return ret;
}
int aff_pt_init(aff_pt_t in, ec_shortw_crv_src_t curve)
{
int ret;
MUST_HAVE((in != NULL), ret, err);
MUST_HAVE((curve != NULL), ret, err);
ret = ec_shortw_crv_check_initialized(curve); EG(ret, err);
ret = fp_init(&(in->x), curve->a.ctx); EG(ret, err);
ret = fp_init(&(in->y), curve->a.ctx); EG(ret, err);
in->crv = curve;
in->magic = AFF_PT_MAGIC;
err:
return ret;
}
int aff_pt_init_from_coords(aff_pt_t in,
ec_shortw_crv_src_t curve,
fp_src_t xcoord, fp_src_t ycoord)
{
int ret;
ret = aff_pt_init(in, curve); EG(ret, err);
ret = fp_copy(&(in->x), xcoord); EG(ret, err);
ret = fp_copy(&(in->y), ycoord);
err:
return ret;
}
void aff_pt_uninit(aff_pt_t in)
{
if((in != NULL) && (in->magic == AFF_PT_MAGIC) && (in->crv != NULL)){
in->crv = NULL;
in->magic = WORD(0);
fp_uninit(&(in->x));
fp_uninit(&(in->y));
}
return;
}
int aff_pt_y_from_x(fp_t y1, fp_t y2, fp_src_t x, ec_shortw_crv_src_t curve)
{
int ret;
MUST_HAVE((y1 != NULL) && (y2 != NULL), ret, err);
ret = ec_shortw_crv_check_initialized(curve); EG(ret, err);
ret = fp_check_initialized(x); EG(ret, err);
MUST_HAVE((y1 != y2) && (y1 != x), ret, err);
ret = fp_copy(y1, x); EG(ret, err);
ret = fp_copy(y2, x); EG(ret, err);
ret = fp_sqr(y1, y1); EG(ret, err);
ret = fp_mul(y1, y1, x); EG(ret, err);
ret = fp_mul(y2, y2, &(curve->a)); EG(ret, err);
ret = fp_add(y1, y1, y2); EG(ret, err);
ret = fp_add(y1, y1, &(curve->b)); EG(ret, err);
ret = fp_sqrt(y1, y2, y1);
err:
return ret;
}
int is_on_shortw_curve(fp_src_t x, fp_src_t y, ec_shortw_crv_src_t curve, int *on_curve)
{
fp tmp1, tmp2;
int ret, cmp;
tmp1.magic = tmp2.magic = WORD(0);
ret = ec_shortw_crv_check_initialized(curve); EG(ret, err);
ret = fp_check_initialized(x); EG(ret, err);
ret = fp_check_initialized(y); EG(ret, err);
MUST_HAVE((on_curve != NULL), ret, err);
MUST_HAVE((x->ctx == y->ctx), ret, err);
MUST_HAVE((x->ctx == curve->a.ctx), ret, err);
ret = fp_init(&tmp1, x->ctx); EG(ret, err);
ret = fp_sqr(&tmp1, y); EG(ret, err);
ret = fp_sub(&tmp1, &tmp1, &(curve->b)); EG(ret, err);
ret = fp_init(&tmp2, x->ctx); EG(ret, err);
ret = fp_sqr(&tmp2, x); EG(ret, err);
ret = fp_add(&tmp2, &tmp2, &(curve->a)); EG(ret, err);
ret = fp_mul(&tmp2, &tmp2, x); EG(ret, err);
ret = fp_cmp(&tmp1, &tmp2, &cmp); EG(ret, err);
(*on_curve) = (!cmp);
err:
fp_uninit(&tmp1);
fp_uninit(&tmp2);
return ret;
}
int aff_pt_is_on_curve(aff_pt_src_t pt, int *on_curve)
{
int ret;
MUST_HAVE((on_curve != NULL), ret, err);
ret = aff_pt_check_initialized(pt); EG(ret, err);
ret = is_on_shortw_curve(&(pt->x), &(pt->y), pt->crv, on_curve);
err:
return ret;
}
int ec_shortw_aff_copy(aff_pt_t out, aff_pt_src_t in)
{
int ret;
ret = aff_pt_check_initialized(in); EG(ret, err);
ret = aff_pt_init(out, in->crv); EG(ret, err);
ret = fp_copy(&(out->x), &(in->x)); EG(ret, err);
ret = fp_copy(&(out->y), &(in->y));
err:
return ret;
}
int ec_shortw_aff_cmp(aff_pt_src_t in1, aff_pt_src_t in2, int *cmp)
{
int ret, cmp_x, cmp_y;
MUST_HAVE((cmp != NULL), ret, err);
ret = aff_pt_check_initialized(in1); EG(ret, err);
ret = aff_pt_check_initialized(in2); EG(ret, err);
MUST_HAVE((in1->crv == in2->crv), ret, err);
ret = fp_cmp(&(in1->x), &(in2->x), &cmp_x); EG(ret, err);
ret = fp_cmp(&(in1->y), &(in2->y), &cmp_y); EG(ret, err);
(*cmp) = (cmp_x | cmp_y);
err:
return ret;
}
int ec_shortw_aff_eq_or_opp(aff_pt_src_t in1, aff_pt_src_t in2,
int *aff_is_eq_or_opp)
{
int ret, cmp, eq_or_opp;
ret = aff_pt_check_initialized(in1); EG(ret, err);
ret = aff_pt_check_initialized(in2); EG(ret, err);
MUST_HAVE((in1->crv == in2->crv), ret, err);
MUST_HAVE((aff_is_eq_or_opp != NULL), ret, err);
ret = fp_cmp(&(in1->x), &(in2->x), &cmp); EG(ret, err);
ret = fp_eq_or_opp(&(in1->y), &(in2->y), &eq_or_opp); EG(ret, err);
(*aff_is_eq_or_opp) = ((cmp == 0) & eq_or_opp);
err:
return ret;
}
int aff_pt_import_from_buf(aff_pt_t pt,
const u8 *pt_buf,
u16 pt_buf_len, ec_shortw_crv_src_t crv)
{
fp_ctx_src_t ctx;
u16 coord_len;
int ret, on_curve;
MUST_HAVE((pt_buf != NULL), ret, err);
MUST_HAVE((pt != NULL), ret, err);
ret = ec_shortw_crv_check_initialized(crv); EG(ret, err);
ctx = crv->a.ctx;
coord_len = (u16)BYTECEIL(ctx->p_bitlen);
MUST_HAVE((pt_buf_len == (2 * coord_len)), ret, err);
ret = fp_init_from_buf(&(pt->x), ctx, pt_buf, coord_len); EG(ret, err);
ret = fp_init_from_buf(&(pt->y), ctx, pt_buf + coord_len, coord_len); EG(ret, err);
pt->crv = crv;
pt->magic = AFF_PT_MAGIC;
ret = aff_pt_is_on_curve(pt, &on_curve); EG(ret, err);
if (!on_curve) {
aff_pt_uninit(pt);
ret = -1;
} else {
ret = 0;
}
err:
PTR_NULLIFY(ctx);
return ret;
}
int aff_pt_export_to_buf(aff_pt_src_t pt, u8 *pt_buf, u32 pt_buf_len)
{
u16 coord_len;
int ret, on_curve;
MUST_HAVE((pt_buf != NULL), ret, err);
ret = aff_pt_is_on_curve(pt, &on_curve); EG(ret, err);
MUST_HAVE((on_curve), ret, err);
coord_len = (u16)BYTECEIL(pt->crv->a.ctx->p_bitlen);
MUST_HAVE((pt_buf_len == (2 * coord_len)), ret, err);
ret = fp_export_to_buf(pt_buf, coord_len, &(pt->x)); EG(ret, err);
ret = fp_export_to_buf(pt_buf + coord_len, coord_len, &(pt->y));
err:
return ret;
}