From cf085802a34b8e2b21ca5d72db6fd8627f8103b6 Mon Sep 17 00:00:00 2001 From: "Diego F. Aranha" Date: Fri, 29 Mar 2024 02:26:29 +0100 Subject: [PATCH] Big refactoring of the EP module. --- include/relic_core.h | 4 - include/relic_ep.h | 2 + include/relic_fp.h | 2 + src/ep/relic_ep_add.c | 617 +-------------- src/ep/relic_ep_curve.c | 27 - src/ep/relic_ep_dbl.c | 18 +- src/ep/relic_ep_map.c | 2 +- src/ep/relic_ep_param.c | 28 + src/epx/relic_ep2_add.c | 63 +- src/epx/relic_ep2_curve.c | 17 + src/epx/relic_ep2_map.c | 2 +- src/epx/relic_ep2_mul_cof.c | 1 - src/epx/relic_ep3_add.c | 71 +- src/epx/relic_ep3_mul_cof.c | 1 - src/epx/relic_ep4_add.c | 71 +- src/epx/relic_ep4_mul_cof.c | 1 - src/epx/relic_ep8_add.c | 71 +- src/epx/relic_ep8_mul_cof.c | 1 - src/fp/relic_fp_param.c | 18 + src/tmpl/relic_ep_add_tmpl.h | 706 ++++++++++++++++++ .../{relic_tmpl_map.h => relic_ep_map_tmpl.h} | 4 +- 21 files changed, 818 insertions(+), 909 deletions(-) create mode 100644 src/tmpl/relic_ep_add_tmpl.h rename src/tmpl/{relic_tmpl_map.h => relic_ep_map_tmpl.h} (98%) diff --git a/include/relic_core.h b/include/relic_core.h index ae3b08241..92bbbd580 100644 --- a/include/relic_core.h +++ b/include/relic_core.h @@ -267,8 +267,6 @@ typedef struct _ctx_t { fp_st ep_a; /** The b-coefficient of the elliptic curve. */ fp_st ep_b; - /** The value 3b used in elliptic curve arithmetic. */ - fp_st ep_b3; /** The generator of the elliptic curve. */ ep_st ep_g; /** The order of the group of points in the elliptic curve. */ @@ -292,8 +290,6 @@ typedef struct _ctx_t { int ep_opt_a; /** Optimization identifier for the b-coefficient. */ int ep_opt_b; - /** Optimization identifier for the b3 value. */ - int ep_opt_b3; /** Flag that stores if the prime curve has efficient endomorphisms. */ int ep_is_endom; /** Flag that stores if the prime curve is supersingular. */ diff --git a/include/relic_ep.h b/include/relic_ep.h index 5e5cdc5a7..6579f6ae9 100644 --- a/include/relic_ep.h +++ b/include/relic_ep.h @@ -183,6 +183,8 @@ enum { N16_P766, /* Fotiadis-Moartindale with embedding degree 18. */ FM18_P768, + /** Barreto-Lynn-Scott curve with embedding degree 12. */ + B12_P1150, /** 1536-bit supersingular curve. */ SS_P1536, /** 3072-bit supersingular curve. */ diff --git a/include/relic_fp.h b/include/relic_fp.h index 4bcff5b3b..061a885d0 100644 --- a/include/relic_fp.h +++ b/include/relic_fp.h @@ -166,6 +166,8 @@ enum { FM18_768, /** 1024-bit prime for CTIDH. */ CTIDH_1024, + /** 1150-bit prime for BLS curve with embedding degree 12. */ + B12_1150, /** 1536-bit prime for supersingular curve with embedding degree k = 2. */ SS_1536, /** 2048-bit prime for CTDIH. */ diff --git a/src/ep/relic_ep_add.c b/src/ep/relic_ep_add.c index e8694421c..dec994be7 100644 --- a/src/ep/relic_ep_add.c +++ b/src/ep/relic_ep_add.c @@ -30,6 +30,7 @@ */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -46,70 +47,7 @@ * @param[in] p - the first point to add. * @param[in] q - the second point to add. */ -static void ep_add_basic_imp(ep_t r, fp_t s, const ep_t p, const ep_t q) { - fp_t t0, t1, t2; - - fp_null(t0); - fp_null(t1); - fp_null(t2); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - fp_new(t2); - - /* t0 = x2 - x1. */ - fp_sub(t0, q->x, p->x); - /* t1 = y2 - y1. */ - fp_sub(t1, q->y, p->y); - - /* If t0 is zero. */ - if (fp_is_zero(t0)) { - if (fp_is_zero(t1)) { - /* If t1 is zero, q = p, should have doubled. */ - ep_dbl_basic(r, p); - } else { - /* If t1 is not zero and t0 is zero, q = -p and r = infinity. */ - ep_set_infty(r); - } - } else { - /* t2 = 1/(x2 - x1). */ - fp_inv(t2, t0); - /* t2 = lambda = (y2 - y1)/(x2 - x1). */ - fp_mul(t2, t1, t2); - - /* x3 = lambda^2 - x2 - x1. */ - fp_sqr(t1, t2); - fp_sub(t0, t1, p->x); - fp_sub(t0, t0, q->x); - - /* y3 = lambda * (x1 - x3) - y1. */ - fp_sub(t1, p->x, t0); - fp_mul(t1, t2, t1); - fp_sub(r->y, t1, p->y); - - fp_copy(r->x, t0); - fp_copy(r->z, p->z); - - if (s != NULL) { - fp_copy(s, t2); - } - - r->coord = BASIC; - } - fp_free(t0); - fp_free(t1); - fp_free(t2); - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - } -} +TMPL_ADD_BASIC_IMP(ep, fp); #endif /* EP_ADD == BASIC */ @@ -117,165 +55,13 @@ static void ep_add_basic_imp(ep_t r, fp_t s, const ep_t p, const ep_t q) { /** * Adds a point represented in homogeneous coordinates to a point represented in - * projective coordinates. + * affine coordinates on an ordinary prime elliptic curve. * * @param[out] r - the result. * @param[in] p - the projective point. * @param[in] q - the affine point. */ -static void ep_add_projc_mix(ep_t r, const ep_t p, const ep_t q) { - fp_t t0, t1, t2, t3, t4, t5; - - fp_null(t0); - fp_null(t1); - fp_null(t2); - fp_null(t3); - fp_null(t4); - fp_null(t5); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - fp_new(t2); - fp_new(t3); - fp_new(t4); - fp_new(t5); - - /* Formulas for mixed addition from - * "Complete addition formulas for prime order elliptic curves" - * by Joost Renes, Craig Costello, and Lejla Batina - * https://eprint.iacr.org/2015/1060.pdf - */ - - fp_mul(t0, p->x, q->x); - fp_mul(t1, p->y, q->y); - fp_add(t3, q->x, q->y); - fp_add(t4, p->x, p->y); - fp_mul(t3, t3, t4); - fp_add(t4, t0, t1); - fp_sub(t3, t3, t4); - - if (ep_curve_opt_a() == RLC_ZERO) { - /* Cost of 11M + 2m_3b + 13a. */ - if (p->coord == BASIC) { - /* Save 1M + 1m_3b if z1 = 1. */ - fp_add(t4, q->y, p->y); - fp_add(r->y, q->x, p->x); - fp_add(r->z, t1, ep_curve_get_b3()); - fp_sub(t1, t1, ep_curve_get_b3()); - } else { - fp_mul(t4, q->y, p->z); - fp_add(t4, t4, p->y); - fp_mul(r->y, q->x, p->z); - fp_add(r->y, r->y, p->x); - ep_curve_mul_b3(t2, p->z); - fp_add(r->z, t1, t2); - fp_sub(t1, t1, t2); - } - fp_dbl(r->x, t0); - fp_add(t0, t0, r->x); - ep_curve_mul_b3(r->y, r->y); - fp_mul(r->x, t4, r->y); - fp_mul(t2, t3, t1); - fp_sub(r->x, t2, r->x); - fp_mul(r->y, t0, r->y); - fp_mul(t1, t1, r->z); - fp_add(r->y, t1, r->y); - fp_mul(t0, t0, t3); - fp_mul(r->z, r->z, t4); - fp_add(r->z, r->z, t0); - } else if (ep_curve_opt_a() == RLC_MIN3) { - /* Cost of 11M + 2m_b + 23a. */ - if (p->coord == BASIC) { - /* Save 2M + 3a if z1 = 1. */ - fp_set_dig(t2, 3); - fp_add(t4, q->y, p->y); - fp_add(r->y, q->x, p->x); - fp_sub(r->x, r->y, ep_curve_get_b()); - } else { - fp_dbl(t2, p->z); - fp_add(t2, t2, p->z); - fp_mul(t4, q->y, p->z); - fp_add(t4, t4, p->y); - fp_mul(r->y, q->x, p->z); - fp_add(r->y, r->y, p->x); - ep_curve_mul_b(r->z, p->z); - fp_sub(r->x, r->y, r->z); - } - fp_dbl(r->z, r->x); - fp_add(r->x, r->x, r->z); - fp_sub(r->z, t1, r->x); - fp_add(r->x, t1, r->x); - ep_curve_mul_b(r->y, r->y); - fp_sub(r->y, r->y, t2); - fp_sub(r->y, r->y, t0); - fp_dbl(t1, r->y); - fp_add(r->y, t1, r->y); - fp_dbl(t1, t0); - fp_add(t0, t1, t0); - fp_sub(t0, t0, t2); - fp_mul(t1, t4, r->y); - fp_mul(t2, t0, r->y); - fp_mul(r->y, r->x, r->z); - fp_add(r->y, r->y, t2); - fp_mul(r->x, t3, r->x); - fp_sub(r->x, r->x, t1); - fp_mul(r->z, t4, r->z); - fp_mul(t1, t3, t0); - fp_add(r->z, r->z, t1); - } else { - /* Cost of 11M + 3m_a + 2m_3b + 17a. */ - if (p->coord == BASIC) { - /* Save 1M + 1m_a + 1m_3b if z1 = 1. */ - fp_copy(t2, ep_curve_get_a()); - fp_add(t4, q->x, p->x); - fp_add(t5, q->y, p->y); - ep_curve_mul_a(r->z, t4); - fp_add(r->z, r->z, ep_curve_get_b3()); - } else { - ep_curve_mul_a(t2, p->z); - fp_mul(t4, q->x, p->z); - fp_add(t4, t4, p->x); - fp_mul(t5, q->y, p->z); - fp_add(t5, t5, p->y); - ep_curve_mul_b3(r->x, p->z); - ep_curve_mul_a(r->z, t4); - fp_add(r->z, r->x, r->z); - } - fp_sub(r->x, t1, r->z); - fp_add(r->z, t1, r->z); - fp_mul(r->y, r->x, r->z); - fp_dbl(t1, t0); - fp_add(t1, t1, t0); - ep_curve_mul_b3(t4, t4); - fp_add(t1, t1, t2); - fp_sub(t2, t0, t2); - ep_curve_mul_a(t2, t2); - fp_add(t4, t4, t2); - fp_mul(t0, t1, t4); - fp_add(r->y, r->y, t0); - fp_mul(t0, t5, t4); - fp_mul(r->x, t3, r->x); - fp_sub(r->x, r->x, t0); - fp_mul(t0, t3, t1); - fp_mul(r->z, t5, r->z); - fp_add(r->z, r->z, t0); - } - - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - fp_free(t3); - fp_free(t4); - fp_free(t5); - } -} +TMPL_ADD_PROJC_MIX(ep, fp); /** * Adds two points represented in homogeneous coordinates on an ordinary prime @@ -285,164 +71,7 @@ static void ep_add_projc_mix(ep_t r, const ep_t p, const ep_t q) { * @param[in] p - the first point to add. * @param[in] q - the second point to add. */ -static void ep_add_projc_imp(ep_t r, const ep_t p, const ep_t q) { -#if defined(EP_MIXED) && defined(STRIP) - /* If code size is a problem, leave only the mixed version. */ - ep_add_projc_mix(r, p, q); -#else /* General addition. */ - -#if defined(EP_MIXED) || !defined(STRIP) - /* Test if z2 = 1 only if mixed coordinates are turned on. */ - if (q->coord == BASIC) { - ep_add_projc_mix(r, p, q); - return; - } -#endif - fp_t t0, t1, t2, t3, t4, t5; - - fp_null(t0); - fp_null(t1); - fp_null(t2); - fp_null(t3); - fp_null(t4); - fp_null(t5); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - fp_new(t2); - fp_new(t3); - fp_new(t4); - fp_new(t5); - - /* Formulas for point addition from - * "Complete addition formulas for prime order elliptic curves" - * by Joost Renes, Craig Costello, and Lejla Batina - * https://eprint.iacr.org/2015/1060.pdf - */ - fp_mul(t0, p->x, q->x); - fp_mul(t1, p->y, q->y); - fp_mul(t2, p->z, q->z); - fp_add(t3, p->x, p->y); - fp_add(t4, q->x, q->y); - fp_mul(t3, t3, t4); - fp_add(t4, t0, t1); - fp_sub(t3, t3, t4); - if (ep_curve_opt_a() == RLC_ZERO) { - /* Cost of 12M + 2m_3b + 19a. */ - fp_add(t4, p->y, p->z); - fp_add(t5, q->y, q->z); - fp_mul(t4, t4, t5); - fp_add(t5, t1, t2); - fp_sub(t4, t4, t5); - fp_add(r->y, q->x, q->z); - fp_add(r->x, p->x, p->z); - fp_mul(r->x, r->x, r->y); - fp_add(r->y, t0, t2); - fp_sub(r->y, r->x, r->y); - fp_dbl(r->x, t0); - fp_add(t0, t0, r->x); - ep_curve_mul_b3(t2, t2); - fp_add(r->z, t1, t2); - fp_sub(t1, t1, t2); - ep_curve_mul_b3(r->y, r->y); - fp_mul(r->x, t4, r->y); - fp_mul(t2, t3, t1); - fp_sub(r->x, t2, r->x); - fp_mul(r->y, t0, r->y); - fp_mul(t1, t1, r->z); - fp_add(r->y, t1, r->y); - fp_mul(t0, t0, t3); - fp_mul(r->z, r->z, t4); - fp_add(r->z, r->z, t0); - } else if (ep_curve_opt_a() == RLC_MIN3) { - /* Cost of 12M + 2m_b + 29a. */ - fp_add(t4, p->y, p->z); - fp_add(t5, q->y, q->z); - fp_mul(t4, t4, t5); - fp_add(t5, t1, t2); - fp_sub(t4, t4, t5); - fp_add(r->x, p->x, p->z); - fp_add(r->y, q->x, q->z); - fp_mul(r->x, r->x, r->y); - fp_add(r->y, t0, t2); - fp_sub(r->y, r->x, r->y); - ep_curve_mul_b(r->z, t2); - fp_sub(r->x, r->y, r->z); - fp_dbl(r->z, r->x); - fp_add(r->x, r->x, r->z); - fp_sub(r->z, t1, r->x); - fp_add(r->x, t1, r->x); - ep_curve_mul_b(r->y, r->y); - fp_dbl(t1, t2); - fp_add(t2, t1, t2); - fp_sub(r->y, r->y, t2); - fp_sub(r->y, r->y, t0); - fp_dbl(t1, r->y); - fp_add(r->y, t1, r->y); - fp_dbl(t1, t0); - fp_add(t0, t1, t0); - fp_sub(t0, t0, t2); - fp_mul(t1, t4, r->y); - fp_mul(t2, t0, r->y); - fp_mul(r->y, r->x, r->z); - fp_add(r->y, r->y, t2); - fp_mul(r->x, t3, r->x); - fp_sub(r->x, r->x, t1); - fp_mul(r->z, t4, r->z); - fp_mul(t1, t3, t0); - fp_add(r->z, r->z, t1); - } else { - /* Cost of 12M + 3m_a + 2_m3b + 23a. */ - fp_add(t4, p->x, p->z); - fp_add(t5, q->x, q->z); - fp_mul(t4, t4, t5); - fp_add(t5, t0, t2); - fp_sub(t4, t4, t5); - fp_add(t5, p->y, p->z); - fp_add(r->x, q->y, q->z); - fp_mul(t5, t5, r->x); - fp_add(r->x, t1, t2); - fp_sub(t5, t5, r->x); - ep_curve_mul_a(r->z, t4); - ep_curve_mul_b3(r->x, t2); - fp_add(r->z, r->x, r->z); - fp_sub(r->x, t1, r->z); - fp_add(r->z, t1, r->z); - fp_mul(r->y, r->x, r->z); - fp_dbl(t1, t0); - fp_add(t1, t1, t0); - ep_curve_mul_a(t2, t2); - ep_curve_mul_b3(t4, t4); - fp_add(t1, t1, t2); - fp_sub(t2, t0, t2); - ep_curve_mul_a(t2, t2); - fp_add(t4, t4, t2); - fp_mul(t0, t1, t4); - fp_add(r->y, r->y, t0); - fp_mul(t0, t5, t4); - fp_mul(r->x, t3, r->x); - fp_sub(r->x, r->x, t0); - fp_mul(t0, t3, t1); - fp_mul(r->z, t5, r->z); - fp_add(r->z, r->z, t0); - } - - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - fp_free(t3); - fp_free(t4); - fp_free(t5); - } -#endif -} +TMPL_ADD_PROJC_IMP(ep, fp); #endif /* EP_ADD == PROJC */ @@ -450,123 +79,13 @@ static void ep_add_projc_imp(ep_t r, const ep_t p, const ep_t q) { /** * Adds a point represented in Jacobian coordinates to a point represented in - * projective coordinates. + * affine coordinates on an ordinary prime elliptic curve. * * @param[out] r - the result. * @param[in] p - the projective point. * @param[in] q - the affine point. */ -static void ep_add_jacob_mix(ep_t r, const ep_t p, const ep_t q) { - fp_t t0, t1, t2, t3, t4, t5, t6; - - fp_null(t0); - fp_null(t1); - fp_null(t2); - fp_null(t3); - fp_null(t4); - fp_null(t5); - fp_null(t6); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - fp_new(t2); - fp_new(t3); - fp_new(t4); - fp_new(t5); - fp_new(t6); - - /* madd-2007-bl formulas: 7M + 4S + 9add + 1*4 + 3*2. */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-madd-2007-bl */ - - if (p->coord != BASIC) { - /* t0 = z1^2. */ - fp_sqr(t0, p->z); - - /* t3 = U2 = x2 * z1^2. */ - fp_mul(t3, q->x, t0); - - /* t1 = S2 = y2 * z1^3. */ - fp_mul(t1, t0, p->z); - fp_mul(t1, t1, q->y); - - /* t3 = H = U2 - x1. */ - fp_sub(t3, t3, p->x); - - /* t1 = R = 2 * (S2 - y1). */ - fp_sub(t1, t1, p->y); - fp_dbl(t1, t1); - } else { - /* H = x2 - x1. */ - fp_sub(t3, q->x, p->x); - - /* t1 = R = 2 * (y2 - y1). */ - fp_sub(t1, q->y, p->y); - fp_dbl(t1, t1); - } - - /* t2 = HH = H^2. */ - fp_sqr(t2, t3); - - /* If H is zero. */ - if (fp_is_zero(t3)) { - if (fp_is_zero(t1)) { - /* If I is zero, p = q, should have doubled. */ - ep_dbl_jacob(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep_set_infty(r); - } - } else { - /* t4 = I = 4*HH. */ - fp_dbl(t4, t2); - fp_dbl(t4, t4); - - /* t5 = J = H * I. */ - fp_mul(t5, t3, t4); - - /* t4 = V = x1 * I. */ - fp_mul(t4, p->x, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp_sqr(r->x, t1); - fp_sub(r->x, r->x, t5); - fp_dbl(t6, t4); - fp_sub(r->x, r->x, t6); - - /* y3 = R * (V - x3) - 2 * Y1 * J. */ - fp_sub(t4, t4, r->x); - fp_mul(t4, t4, t1); - fp_mul(t1, p->y, t5); - fp_dbl(t1, t1); - fp_sub(r->y, t4, t1); - - if (p->coord != BASIC) { - /* z3 = (z1 + H)^2 - z1^2 - HH. */ - fp_add(r->z, p->z, t3); - fp_sqr(r->z, r->z); - fp_sub(r->z, r->z, t0); - fp_sub(r->z, r->z, t2); - } else { - /* z3 = 2 * H. */ - fp_dbl(r->z, t3); - } - } - r->coord = JACOB; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - fp_free(t3); - fp_free(t4); - fp_free(t5); - fp_free(t6); - } -} +TMPL_ADD_JACOB_MIX(ep, fp); /** * Adds two points represented in Jacobian coordinates on an ordinary prime @@ -576,127 +95,7 @@ static void ep_add_jacob_mix(ep_t r, const ep_t p, const ep_t q) { * @param[in] p - the first point to add. * @param[in] q - the second point to add. */ -static void ep_add_jacob_imp(ep_t r, const ep_t p, const ep_t q) { -#if defined(EP_MIXED) && defined(STRIP) - /* If code size is a problem, leave only the mixed version. */ - ep_add_jacob_mix(r, p, q); -#else /* General addition. */ - -#if defined(EP_MIXED) || !defined(STRIP) - /* Test if z2 = 1 only if mixed coordinates are turned on. */ - if (q->coord == BASIC) { - ep_add_jacob_mix(r, p, q); - return; - } -#endif - - fp_t t0, t1, t2, t3, t4, t5, t6; - - fp_null(t0); - fp_null(t1); - fp_null(t2); - fp_null(t3); - fp_null(t4); - fp_null(t5); - fp_null(t6); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - fp_new(t2); - fp_new(t3); - fp_new(t4); - fp_new(t5); - fp_new(t6); - - /* add-2007-bl formulas: 11M + 5S + 9add + 4*2 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl */ - - /* t0 = z1^2. */ - fp_sqr(t0, p->z); - - /* t1 = z2^2. */ - fp_sqr(t1, q->z); - - /* t2 = U1 = x1 * z2^2. */ - fp_mul(t2, p->x, t1); - - /* t3 = U2 = x2 * z1^2. */ - fp_mul(t3, q->x, t0); - - /* t6 = z1^2 + z2^2. */ - fp_add(t6, t0, t1); - - /* t0 = S2 = y2 * z1^3. */ - fp_mul(t0, t0, p->z); - fp_mul(t0, t0, q->y); - - /* t1 = S1 = y1 * z2^3. */ - fp_mul(t1, t1, q->z); - fp_mul(t1, t1, p->y); - - /* t3 = H = U2 - U1. */ - fp_sub(t3, t3, t2); - - /* t0 = R = 2 * (S2 - S1). */ - fp_sub(t0, t0, t1); - fp_dbl(t0, t0); - - /* If E is zero. */ - if (fp_is_zero(t3)) { - if (fp_is_zero(t0)) { - /* If I is zero, p = q, should have doubled. */ - ep_dbl_jacob(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep_set_infty(r); - } - } else { - /* t4 = I = (2*H)^2. */ - fp_dbl(t4, t3); - fp_sqr(t4, t4); - - /* t5 = J = H * I. */ - fp_mul(t5, t3, t4); - - /* t4 = V = U1 * I. */ - fp_mul(t4, t2, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp_sqr(r->x, t0); - fp_sub(r->x, r->x, t5); - fp_dbl(t2, t4); - fp_sub(r->x, r->x, t2); - - /* y3 = R * (V - x3) - 2 * S1 * J. */ - fp_sub(t4, t4, r->x); - fp_mul(t4, t4, t0); - fp_mul(t1, t1, t5); - fp_dbl(t1, t1); - fp_sub(r->y, t4, t1); - - /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ - fp_add(r->z, p->z, q->z); - fp_sqr(r->z, r->z); - fp_sub(r->z, r->z, t6); - fp_mul(r->z, r->z, t3); - } - r->coord = JACOB; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - fp_free(t3); - fp_free(t4); - fp_free(t5); - fp_free(t6); - } -#endif -} +TMPL_ADD_JACOB_IMP(ep, fp); #endif /* EP_ADD == JACOB */ diff --git a/src/ep/relic_ep_curve.c b/src/ep/relic_ep_curve.c index 6d2d9a2a3..aa7f4debb 100644 --- a/src/ep/relic_ep_curve.c +++ b/src/ep/relic_ep_curve.c @@ -203,12 +203,9 @@ static void ep_curve_set(const fp_t a, const fp_t b, const ep_t g, const bn_t r, fp_copy(ctx->ep_a, a); fp_copy(ctx->ep_b, b); - fp_dbl(ctx->ep_b3, b); - fp_add(ctx->ep_b3, ctx->ep_b3, b); detect_opt(&(ctx->ep_opt_a), ctx->ep_a); detect_opt(&(ctx->ep_opt_b), ctx->ep_b); - detect_opt(&(ctx->ep_opt_b3), ctx->ep_b3); ctx->ep_is_ctmap = ctmap; ep_curve_set_map(); @@ -266,10 +263,6 @@ dig_t *ep_curve_get_b(void) { return core_get()->ep_b; } -dig_t *ep_curve_get_b3(void) { - return core_get()->ep_b3; -} - #if defined(EP_ENDOM) && (EP_MUL == LWNAF || EP_FIX == COMBS || EP_FIX == LWNAF || EP_SIM == INTER || !defined(STRIP)) dig_t *ep_curve_get_beta(void) { @@ -340,26 +333,6 @@ void ep_curve_mul_b(fp_t c, const fp_t a) { } } -void ep_curve_mul_b3(fp_t c, const fp_t a) { - ctx_t *ctx = core_get(); - switch (ctx->ep_opt_b3) { - case RLC_ZERO: - fp_zero(c); - break; - case RLC_ONE: - fp_copy(c, a); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_mul_dig(c, a, ctx->ep_b3[0]); - break; -#endif - default: - fp_mul(c, a, ctx->ep_b3); - break; - } -} - int ep_curve_is_endom(void) { return core_get()->ep_is_endom; } diff --git a/src/ep/relic_ep_dbl.c b/src/ep/relic_ep_dbl.c index 1a160d02c..b1a6ecafc 100644 --- a/src/ep/relic_ep_dbl.c +++ b/src/ep/relic_ep_dbl.c @@ -159,11 +159,14 @@ static void ep_dbl_projc_imp(ep_t r, const ep_t p) { if (p->coord == BASIC) { /* Save 1M + 1S + 1m_b3 if z1 = 1. */ fp_copy(t1, p->y); - fp_copy(t2, ep_curve_get_b3()); + fp_dbl(t2, ep_curve_get_b()); + fp_add(t2, t2, ep_curve_get_b()); } else { fp_mul(t1, p->y, p->z); fp_sqr(t2, p->z); - ep_curve_mul_b3(t2, t2); + fp_dbl(t5, t2); + fp_add(t5, t5, t2); + ep_curve_mul_b(t2, t5); } fp_dbl(r->z, t0); fp_dbl(r->z, r->z); @@ -218,11 +221,14 @@ static void ep_dbl_projc_imp(ep_t r, const ep_t p) { /* Common cost of 8M + 3S + 3m_a + 2m_3b + 15a. */ if (p->coord == BASIC) { /* Save 1S + 1m_b + 1m_a if z1 = 1. */ - fp_copy(r->y, ep_curve_get_b3()); + fp_dbl(r->y, ep_curve_get_b()); + fp_add(r->y, r->y, ep_curve_get_b()); fp_copy(t2, ep_curve_get_a()); } else { fp_sqr(t2, p->z); - ep_curve_mul_b3(r->y, t2); + fp_dbl(t5, t2); + fp_add(t5, t5, t2); + ep_curve_mul_b(r->y, t5); ep_curve_mul_a(t2, t2); } fp_mul(r->z, p->x, p->z); @@ -233,7 +239,9 @@ static void ep_dbl_projc_imp(ep_t r, const ep_t p) { fp_add(r->y, t1, r->y); fp_mul(r->y, r->x, r->y); fp_mul(r->x, t3, r->x); - ep_curve_mul_b3(r->z, r->z); + fp_dbl(t5, r->z); + fp_add(t5, t5, r->z); + ep_curve_mul_b(r->z, t5); fp_sub(t3, t0, t2); ep_curve_mul_a(t3, t3); fp_add(t3, t3, r->z); diff --git a/src/ep/relic_ep_map.c b/src/ep/relic_ep_map.c index 97cbaedfe..f07b6aac0 100644 --- a/src/ep/relic_ep_map.c +++ b/src/ep/relic_ep_map.c @@ -31,7 +31,7 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" +#include "relic_ep_map_tmpl.h" /*============================================================================*/ /* Private definitions */ diff --git a/src/ep/relic_ep_param.c b/src/ep/relic_ep_param.c index 253c47560..e14a85302 100644 --- a/src/ep/relic_ep_param.c +++ b/src/ep/relic_ep_param.c @@ -714,6 +714,20 @@ /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 1150 +/** + * Parameters for a 383-bit pairing-friendly prime curve. + */ +/** @{ */ +#define B12_P1150_A "0" +#define B12_P1150_B "1" +#define B12_P1150_X "1C9E4A85748AF56BFCDB28AA09E80CF55FFED5E25D92B882B3CAB4202EDA1DEAA62DA8D3B9C204FF9C0647A1BCC17EB60CB7F57D1FA5CFE131200DC511C6636B898515C2C714B1F07ADFB97874E7B9E22D3D7206B327792949E05EA8B5CAF91AA486D72C522A4BDD387B63E5EF12374F1FB766B86CE65ACAC5EF3E05826EC1AE3C18D2A14C1181915DA9A7C3760152D1" +#define B12_P1150_Y "3116D7FDB1130460DF71722020D3B32FBBBB01A6A77C999B13EE9C0C3DE4D6CA81E886AC80F933A31A78F0850DD9ED0A8DE122C179481FEF031A50910D7A726BB3F1BAE5E8AC186EDEE69C85A043169308C06B4277E65BDE0AD872F58938F84033ED21E9DC0A6DEE2957BA884AE9582CE5AD88C00CFA4D323E686FF864F872C2EEAD356A43E9BB4A59452C08F4E89E9A" +#define B12_P1150_R "C5C1000000000000001B30F00000000000003622EC6000034BC000057869AF00005703000575ED588100ABBDB4005D60C600000BA2C6103D98AD58000B730C000210975450006301E00100052800004000108000050000000000200000000001" +#define B12_P1150_H "4B00000000000000000528000000000000000A16B00000014000000058000000000B00000055555555556AAAAAAAAAAC" +/** @} */ +#endif + #if defined(EP_SUPER) && FP_PRIME == 1536 /** * Parameters for a 1536-bit supersingular elliptic curve. @@ -1189,6 +1203,13 @@ void ep_param_set(int param) { pairf = EP_FM18; break; #endif +#if defined(EP_ENDOM) && FP_PRIME == 1150 + case B12_P1150: + ASSIGN(B12_P1150, B12_1150); + endom = 1; + pairf = EP_B12; + break; +#endif #if defined(EP_SUPER) && FP_PRIME == 1536 case SS_P1536: ASSIGN(SS_P1536, SS_1536); @@ -1471,6 +1492,8 @@ int ep_param_set_any_endom(void) { ep_param_set(N16_P766); #elif FP_PRIME == 768 ep_param_set(FM18_P768); +#elif FP_PRIME == 1150 + ep_param_set(B12_P1150); #else r = RLC_ERR; #endif @@ -1597,6 +1620,10 @@ int ep_param_set_any_pairf(void) { ep_param_set(FM18_P768); type = RLC_EP_MTYPE; extension = 3; +#elif FP_PRIME == 1150 + ep_param_set(B12_P1150); + type = RLC_EP_MTYPE; + extension = 2; #elif FP_PRIME == 1536 ep_param_set(SS_P1536); extension = 1; @@ -1817,6 +1844,7 @@ int ep_param_level(void) { case B12_P455: return 140; case NIST_P384: + case B12_P1150: case FM16_P765: case K16_P766: case FM18_P768: diff --git a/src/epx/relic_ep2_add.c b/src/epx/relic_ep2_add.c index 2e4f563dc..f793de14a 100644 --- a/src/epx/relic_ep2_add.c +++ b/src/epx/relic_ep2_add.c @@ -31,6 +31,7 @@ */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -47,67 +48,7 @@ * @param p - the first point to add. * @param q - the second point to add. */ -static void ep2_add_basic_imp(ep2_t r, fp2_t s, const ep2_t p, const ep2_t q) { - fp2_t t0, t1, t2; - - fp2_null(t0); - fp2_null(t1); - fp2_null(t2); - - RLC_TRY { - fp2_new(t0); - fp2_new(t1); - fp2_new(t2); - - /* t0 = x2 - x1. */ - fp2_sub(t0, q->x, p->x); - /* t1 = y2 - y1. */ - fp2_sub(t1, q->y, p->y); - - /* If t0 is zero. */ - if (fp2_is_zero(t0)) { - if (fp2_is_zero(t1)) { - /* If t1 is zero, q = p, should have doubled. */ - ep2_dbl_slp_basic(r, s, p); - } else { - /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ - ep2_set_infty(r); - } - } else { - /* t2 = 1/(x2 - x1). */ - fp2_inv(t2, t0); - /* t2 = lambda = (y2 - y1)/(x2 - x1). */ - fp2_mul(t2, t1, t2); - - /* x3 = lambda^2 - x2 - x1. */ - fp2_sqr(t1, t2); - fp2_sub(t0, t1, p->x); - fp2_sub(t0, t0, q->x); - - /* y3 = lambda * (x1 - x3) - y1. */ - fp2_sub(t1, p->x, t0); - fp2_mul(t1, t2, t1); - fp2_sub(r->y, t1, p->y); - - fp2_copy(r->x, t0); - fp2_copy(r->z, p->z); - - if (s != NULL) { - fp2_copy(s, t2); - } - - r->coord = BASIC; - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); - fp2_free(t2); - } -} +TMPL_ADD_BASIC_IMP(ep2, fp2); #endif /* EP_ADD == BASIC */ diff --git a/src/epx/relic_ep2_curve.c b/src/epx/relic_ep2_curve.c index 3ec781ba0..5af21b291 100644 --- a/src/epx/relic_ep2_curve.c +++ b/src/epx/relic_ep2_curve.c @@ -275,6 +275,23 @@ /** @} */ #endif +#if defined(EP_ENDOM) && FP_PRIME == 638 +/** @{ */ +#define B12_1150_A0 "0" +#define B12_1150_A1 "0" +#define B12_1150_B0 "4" +#define B12_1150_B1 "4" +#define B12_1150_X0 "3C57F8F05130D336804E30CAA7BB45E06244DFC0BA836056B036038703719449A42CCC7C34452B4EE2DCA3CBCE0B7637E14E9CA88BDEF105440FB3F84AA95C75DE0BA05686394492B8648BB71D5E7F39" +#define B12_1150_X1 "07B30040203566584002D6DBB49A3DA1D99ECA3CBCD113C07E0CF1FFB3FA4F87F034A034C86F56DB380F2810AC329ED8BD6FE0F4D5C1FA26949739AF82D3AAD4702D2186862B0293E16C5EDDDDA3C922" +#define B12_1150_Y0 "29ED1A1C4F3F5AFC64AB2BA97CFA4D17998061179331A1C34E024B7D82134C60A3569F644E4155753C48698C8A01C80C0C3CEC9E3BDE2E5E22D81BBB514FD24DE186FEBA69B82E88809BFCCE51A1840F" +#define B12_1150_Y1 "3795191221DB4917EEE4B7B85BC7D7CA0C60E82116064463FED0892BA82ACECF905E6DB8083C5F589F04DB80E3203C1B2BEB52ACDED6DF96FC515F36761E7152AEED13369A504FE38C4FF93860B89550" +#define B12_1150_R "50F94035FF4000FFFFFFFFFFF9406BFDC0040000000000000035FB801DFFBFFFFFFFFFFFFFFF401BFF80000000000000000000FFC01" +#define B12_1150_H "2D88688DBA18275F5801BFFD4DDE93725697788C46C7B4BC8050639BA17EA2158B6784CCACDDECE490643943E5376D29C71C96B894056CCCC13C3DC6AAAAAA0F89601DC2979B3721C71C71C8B38CB8AEFEEB9E1C71C71C71C4B9FED17AE51B8E38E38E38E38FC954E8C65" +#define B12_1150_MAPU0 "0" +#define B12_1150_MAPU1 "1" +/** @} */ +#endif + #if defined(EP_ENDOM) && FP_PRIME == 638 /** @{ */ #define B12_P638_A0 "0" diff --git a/src/epx/relic_ep2_map.c b/src/epx/relic_ep2_map.c index 229d5f349..80f01ac24 100644 --- a/src/epx/relic_ep2_map.c +++ b/src/epx/relic_ep2_map.c @@ -32,7 +32,7 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" +#include "relic_ep_map_tmpl.h" /*============================================================================*/ /* Private definitions */ diff --git a/src/epx/relic_ep2_mul_cof.c b/src/epx/relic_ep2_mul_cof.c index ee8be325a..505e77860 100644 --- a/src/epx/relic_ep2_mul_cof.c +++ b/src/epx/relic_ep2_mul_cof.c @@ -32,7 +32,6 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Private definitions */ diff --git a/src/epx/relic_ep3_add.c b/src/epx/relic_ep3_add.c index 3c3626342..628b48bf4 100644 --- a/src/epx/relic_ep3_add.c +++ b/src/epx/relic_ep3_add.c @@ -31,6 +31,7 @@ */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,72 +43,12 @@ * Adds two points represented in affine coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param s - the resulting slope. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[out] s - the slope. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep3_add_basic_imp(ep3_t r, fp3_t s, const ep3_t p, const ep3_t q) { - fp3_t t0, t1, t2; - - fp3_null(t0); - fp3_null(t1); - fp3_null(t2); - - RLC_TRY { - fp3_new(t0); - fp3_new(t1); - fp3_new(t2); - - /* t0 = x2 - x1. */ - fp3_sub(t0, q->x, p->x); - /* t1 = y2 - y1. */ - fp3_sub(t1, q->y, p->y); - - /* If t0 is zero. */ - if (fp3_is_zero(t0)) { - if (fp3_is_zero(t1)) { - /* If t1 is zero, q = p, should have doubled. */ - ep3_dbl_slp_basic(r, s, p); - } else { - /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ - ep3_set_infty(r); - } - } else { - /* t2 = 1/(x2 - x1). */ - fp3_inv(t2, t0); - /* t2 = lambda = (y2 - y1)/(x2 - x1). */ - fp3_mul(t2, t1, t2); - - /* x3 = lambda^2 - x2 - x1. */ - fp3_sqr(t1, t2); - fp3_sub(t0, t1, p->x); - fp3_sub(t0, t0, q->x); - - /* y3 = lambda * (x1 - x3) - y1. */ - fp3_sub(t1, p->x, t0); - fp3_mul(t1, t2, t1); - fp3_sub(r->y, t1, p->y); - - fp3_copy(r->x, t0); - fp3_copy(r->z, p->z); - - if (s != NULL) { - fp3_copy(s, t2); - } - - r->coord = BASIC; - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); - fp3_free(t2); - } -} +TMPL_ADD_BASIC_IMP(ep3, fp3); #endif /* EP_ADD == BASIC */ diff --git a/src/epx/relic_ep3_mul_cof.c b/src/epx/relic_ep3_mul_cof.c index a0deca806..3c3711ca8 100644 --- a/src/epx/relic_ep3_mul_cof.c +++ b/src/epx/relic_ep3_mul_cof.c @@ -32,7 +32,6 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Private definitions */ diff --git a/src/epx/relic_ep4_add.c b/src/epx/relic_ep4_add.c index 57fda0cfc..3ff25328a 100644 --- a/src/epx/relic_ep4_add.c +++ b/src/epx/relic_ep4_add.c @@ -31,6 +31,7 @@ */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,72 +43,12 @@ * Adds two points represented in affine coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param s - the resulting slope. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[out] s - the slope. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep4_add_basic_imp(ep4_t r, fp4_t s, const ep4_t p, const ep4_t q) { - fp4_t t0, t1, t2; - - fp4_null(t0); - fp4_null(t1); - fp4_null(t2); - - RLC_TRY { - fp4_new(t0); - fp4_new(t1); - fp4_new(t2); - - /* t0 = x2 - x1. */ - fp4_sub(t0, q->x, p->x); - /* t1 = y2 - y1. */ - fp4_sub(t1, q->y, p->y); - - /* If t0 is zero. */ - if (fp4_is_zero(t0)) { - if (fp4_is_zero(t1)) { - /* If t1 is zero, q = p, should have doubled. */ - ep4_dbl_slp_basic(r, s, p); - } else { - /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ - ep4_set_infty(r); - } - } else { - /* t2 = 1/(x2 - x1). */ - fp4_inv(t2, t0); - /* t2 = lambda = (y2 - y1)/(x2 - x1). */ - fp4_mul(t2, t1, t2); - - /* x3 = lambda^2 - x2 - x1. */ - fp4_sqr(t1, t2); - fp4_sub(t0, t1, p->x); - fp4_sub(t0, t0, q->x); - - /* y3 = lambda * (x1 - x3) - y1. */ - fp4_sub(t1, p->x, t0); - fp4_mul(t1, t2, t1); - fp4_sub(r->y, t1, p->y); - - fp4_copy(r->x, t0); - fp4_copy(r->z, p->z); - - if (s != NULL) { - fp4_copy(s, t2); - } - - r->coord = BASIC; - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); - fp4_free(t2); - } -} +TMPL_ADD_BASIC_IMP(ep4, fp4); #endif /* EP_ADD == BASIC */ diff --git a/src/epx/relic_ep4_mul_cof.c b/src/epx/relic_ep4_mul_cof.c index 65d4f7f64..b79aa17b6 100644 --- a/src/epx/relic_ep4_mul_cof.c +++ b/src/epx/relic_ep4_mul_cof.c @@ -32,7 +32,6 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Public definitions */ diff --git a/src/epx/relic_ep8_add.c b/src/epx/relic_ep8_add.c index 15dde9000..e0316eaff 100644 --- a/src/epx/relic_ep8_add.c +++ b/src/epx/relic_ep8_add.c @@ -31,6 +31,7 @@ */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,72 +43,12 @@ * Adds two points represented in affine coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param s - the resulting slope. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[out] s - the slope. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep8_add_basic_imp(ep8_t r, fp8_t s, const ep8_t p, const ep8_t q) { - fp8_t t0, t1, t2; - - fp8_null(t0); - fp8_null(t1); - fp8_null(t2); - - RLC_TRY { - fp8_new(t0); - fp8_new(t1); - fp8_new(t2); - - /* t0 = x2 - x1. */ - fp8_sub(t0, q->x, p->x); - /* t1 = y2 - y1. */ - fp8_sub(t1, q->y, p->y); - - /* If t0 is zero. */ - if (fp8_is_zero(t0)) { - if (fp8_is_zero(t1)) { - /* If t1 is zero, q = p, should have doubled. */ - ep8_dbl_slp_basic(r, s, p); - } else { - /* If t1 is not zero and t0 is zero, q = -p and r = infty. */ - ep8_set_infty(r); - } - } else { - /* t2 = 1/(x2 - x1). */ - fp8_inv(t2, t0); - /* t2 = lambda = (y2 - y1)/(x2 - x1). */ - fp8_mul(t2, t1, t2); - - /* x3 = lambda^2 - x2 - x1. */ - fp8_sqr(t1, t2); - fp8_sub(t0, t1, p->x); - fp8_sub(t0, t0, q->x); - - /* y3 = lambda * (x1 - x3) - y1. */ - fp8_sub(t1, p->x, t0); - fp8_mul(t1, t2, t1); - fp8_sub(r->y, t1, p->y); - - fp8_copy(r->x, t0); - fp8_copy(r->z, p->z); - - if (s != NULL) { - fp8_copy(s, t2); - } - - r->coord = BASIC; - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); - fp8_free(t2); - } -} +TMPL_ADD_BASIC_IMP(ep8, fp8); #endif /* EP_ADD == BASIC */ diff --git a/src/epx/relic_ep8_mul_cof.c b/src/epx/relic_ep8_mul_cof.c index 65f85a660..16b818a53 100644 --- a/src/epx/relic_ep8_mul_cof.c +++ b/src/epx/relic_ep8_mul_cof.c @@ -32,7 +32,6 @@ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Public definitions */ diff --git a/src/fp/relic_fp_param.c b/src/fp/relic_fp_param.c index a3f545520..8ff841371 100644 --- a/src/fp/relic_fp_param.c +++ b/src/fp/relic_fp_param.c @@ -623,6 +623,22 @@ void fp_param_set(int param) { bn_read_str(p, STR_P1024, strlen(STR_P1024), 16); fp_prime_set_dense(p); break; +#elif FP_PRIME == 1150 + case B12_1150: + /* x = -(2^192 - 2^188 + 2^115 + 2^110 + 2^44 + 1 */ + bn_set_2b(t0, 192); + bn_set_2b(t1, 188); + bn_sub(t0, t0, t1); + bn_set_2b(t1, 115); + bn_add(t0, t0, t1); + bn_set_2b(t1, 110); + bn_add(t0, t0, t1); + bn_set_2b(t1, 44); + bn_add(t0, t0, t1); + bn_add_dig(t0, t0, 1); + bn_neg(t0, t0); + fp_prime_set_pairf(t0, EP_B12); + break; #elif FP_PRIME == 1536 case SS_1536: /* x = 2^255 + 2^41 + 1. */ @@ -817,6 +833,8 @@ int fp_param_set_any_tower(void) { //fp_param_set(K16_766); #elif FP_PRIME == 768 fp_param_set(FM18_768); +#elif FP_PRIME == 1150 + fp_param_set(B12_1150); #elif FP_PRIME == 1536 fp_param_set(SS_1536); #elif FP_PRIME == 3072 diff --git a/src/tmpl/relic_ep_add_tmpl.h b/src/tmpl/relic_ep_add_tmpl.h new file mode 100644 index 000000000..bc33bb852 --- /dev/null +++ b/src/tmpl/relic_ep_add_tmpl.h @@ -0,0 +1,706 @@ +/* + * RELIC is an Efficient LIbrary for Cryptography + * Copyright (c) 2024 RELIC Authors + * + * This file is part of RELIC. RELIC is legal property of its developers, + * whose names are not listed here. Please refer to the COPYRIGHT file + * for contact information. + * + * RELIC is free software; you can redistribute it and/or modify it under the + * terms of the version 2.1 (or later) of the GNU Lesser General Public License + * as published by the Free Software Foundation; or version 2.0 of the Apache + * License as published by the Apache Software Foundation. See the LICENSE files + * for more details. + * + * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the LICENSE files for more details. + * + * You should have received a copy of the GNU Lesser General Public or the + * Apache License along with RELIC. If not, see + * or . + */ + +/** + * @file + * + * Template for point addition on prime elliptic curves. + * + * @ingroup tmpl + */ + +#include "relic_core.h" + +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +/** + * Defines a template for point addition in affine coordinates. + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#define TMPL_ADD_BASIC_IMP(C, F) \ + static void C##_add_basic_imp(C##_t r, F##_t s, const C##_t p, \ + const C##_t q) { \ + F##_t t0, t1, t2; \ + \ + F##_null(t0); \ + F##_null(t1); \ + F##_null(t2); \ + \ + RLC_TRY { \ + F##_new(t0); \ + F##_new(t1); \ + F##_new(t2); \ + \ + /* t0 = x2 - x1. */ \ + F##_sub(t0, q->x, p->x); \ + /* t1 = y2 - y1. */ \ + F##_sub(t1, q->y, p->y); \ + \ + /* If t0 is zero. */ \ + if (F##_is_zero(t0)) { \ + if (F##_is_zero(t1)) { \ + /* If t1 is zero, q = p, should have doubled. */ \ + C##_dbl_basic(r, p); \ + } else { \ + /* If t1 != 0 and t0 == 0, q = -p and r = infinity. */ \ + C##_set_infty(r); \ + } \ + } else { \ + /* t2 = 1/(x2 - x1). */ \ + F##_inv(t2, t0); \ + /* t2 = lambda = (y2 - y1)/(x2 - x1). */ \ + F##_mul(t2, t1, t2); \ + \ + /* x3 = lambda^2 - x2 - x1. */ \ + F##_sqr(t1, t2); \ + F##_sub(t0, t1, p->x); \ + F##_sub(t0, t0, q->x); \ + \ + /* y3 = lambda * (x1 - x3) - y1. */ \ + F##_sub(t1, p->x, t0); \ + F##_mul(t1, t2, t1); \ + F##_sub(r->y, t1, p->y); \ + \ + F##_copy(r->x, t0); \ + F##_copy(r->z, p->z); \ + \ + if (s != NULL) { \ + F##_copy(s, t2); \ + } \ + \ + r->coord = BASIC; \ + } \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + } RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + } \ + } \ + +/** + * Defines a template for mixed point addition in homogeneous projective + * coordinates. + * + * Formulas for mixed addition from + * "Complete addition formulas for prime order elliptic curves" + * by Joost Renes, Craig Costello, and Lejla Batina + * https://eprint.iacr.org/2015/1060.pdf + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#define TMPL_ADD_PROJC_MIX(C, F) \ + static void C##_add_projc_mix(C##_t r, const C##_t p, const C##_t q) { \ + F##_t t0, t1, t2, t3, t4, t5; \ + \ + F##_null(t0); \ + F##_null(t1); \ + F##_null(t2); \ + F##_null(t3); \ + F##_null(t4); \ + F##_null(t5); \ + \ + RLC_TRY { \ + F##_new(t0); \ + F##_new(t1); \ + F##_new(t2); \ + F##_new(t3); \ + F##_new(t4); \ + F##_new(t5); \ + \ + F##_mul(t0, p->x, q->x); \ + F##_mul(t1, p->y, q->y); \ + F##_add(t3, q->x, q->y); \ + F##_add(t4, p->x, p->y); \ + F##_mul(t3, t3, t4); \ + F##_add(t4, t0, t1); \ + F##_sub(t3, t3, t4); \ + \ + if (C##_curve_opt_a() == RLC_ZERO) { \ + /* Cost of 11M + 2m_3b + 13a. */ \ + if (p->coord == BASIC) { \ + /* Save 1M + 1m_3b if z1 = 1. */ \ + F##_add(t4, q->y, p->y); \ + F##_add(r->y, q->x, p->x); \ + F##_dbl(t5, C##_curve_get_b()); \ + F##_add(t5, t5, C##_curve_get_b()); \ + F##_add(r->z, t1, t5); \ + F##_sub(t1, t1, t5); \ + } else { \ + F##_mul(t4, q->y, p->z); \ + F##_add(t4, t4, p->y); \ + F##_mul(r->y, q->x, p->z); \ + F##_add(r->y, r->y, p->x); \ + C##_curve_mul_b(t2, p->z); \ + F##_dbl(t5, t2); \ + F##_add(t2, t2, t5); \ + F##_add(r->z, t1, t2); \ + F##_sub(t1, t1, t2); \ + } \ + F##_dbl(r->x, t0); \ + F##_add(t0, t0, r->x); \ + C##_curve_mul_b(r->y, r->y); \ + F##_dbl(t5, r->y); \ + F##_add(r->y, r->y, t5); \ + F##_mul(r->x, t4, r->y); \ + F##_mul(t2, t3, t1); \ + F##_sub(r->x, t2, r->x); \ + F##_mul(r->y, t0, r->y); \ + F##_mul(t1, t1, r->z); \ + F##_add(r->y, t1, r->y); \ + F##_mul(t0, t0, t3); \ + F##_mul(r->z, r->z, t4); \ + F##_add(r->z, r->z, t0); \ + } else if (C##_curve_opt_a() == RLC_MIN3) { \ + /* Cost of 11M + 2m_b + 23a. */ \ + if (p->coord == BASIC) { \ + /* Save 2M + 3a if z1 = 1. */ \ + F##_set_dig(t2, 3); \ + F##_add(t4, q->y, p->y); \ + F##_add(r->y, q->x, p->x); \ + F##_sub(r->x, r->y, C##_curve_get_b()); \ + } else { \ + F##_dbl(t2, p->z); \ + F##_add(t2, t2, p->z); \ + F##_mul(t4, q->y, p->z); \ + F##_add(t4, t4, p->y); \ + F##_mul(r->y, q->x, p->z); \ + F##_add(r->y, r->y, p->x); \ + C##_curve_mul_b(r->z, p->z); \ + F##_sub(r->x, r->y, r->z); \ + } \ + F##_dbl(r->z, r->x); \ + F##_add(r->x, r->x, r->z); \ + F##_sub(r->z, t1, r->x); \ + F##_add(r->x, t1, r->x); \ + C##_curve_mul_b(r->y, r->y); \ + F##_sub(r->y, r->y, t2); \ + F##_sub(r->y, r->y, t0); \ + F##_dbl(t1, r->y); \ + F##_add(r->y, t1, r->y); \ + F##_dbl(t1, t0); \ + F##_add(t0, t1, t0); \ + F##_sub(t0, t0, t2); \ + F##_mul(t1, t4, r->y); \ + F##_mul(t2, t0, r->y); \ + F##_mul(r->y, r->x, r->z); \ + F##_add(r->y, r->y, t2); \ + F##_mul(r->x, t3, r->x); \ + F##_sub(r->x, r->x, t1); \ + F##_mul(r->z, t4, r->z); \ + F##_mul(t1, t3, t0); \ + F##_add(r->z, r->z, t1); \ + } else { \ + /* Cost of 11M + 3m_a + 2m_3b + 17a. */ \ + if (p->coord == BASIC) { \ + /* Save 1M + 1m_a + 1m_3b if z1 = 1. */ \ + F##_copy(t2, C##_curve_get_a()); \ + F##_add(t4, q->x, p->x); \ + F##_add(t5, q->y, p->y); \ + F##_dbl(r->z, t4); \ + F##_add(r->z, r->z, t4); \ + C##_curve_mul_a(r->z, r->z); \ + C##_curve_mul_b(r->z, r->z); \ + } else { \ + C##_curve_mul_a(t2, p->z); \ + F##_mul(t4, q->x, p->z); \ + F##_add(t4, t4, p->x); \ + F##_mul(t5, q->y, p->z); \ + F##_add(t5, t5, p->y); \ + F##_dbl(r->x, p->z); \ + F##_add(r->x, r->x, p->z); \ + F##_dbl(r->y, r->x); \ + F##_add(r->x, r->x, r->y); \ + C##_curve_mul_b(r->x, r->x); \ + C##_curve_mul_a(r->z, t4); \ + F##_add(r->z, r->x, r->z); \ + } \ + F##_sub(r->x, t1, r->z); \ + F##_add(r->z, t1, r->z); \ + F##_mul(r->y, r->x, r->z); \ + F##_dbl(t1, t4); \ + F##_add(t1, t1, t4); \ + C##_curve_mul_b(t4, t1); \ + F##_dbl(t1, t0); \ + F##_add(t1, t1, t0); \ + F##_add(t1, t1, t2); \ + F##_sub(t2, t0, t2); \ + C##_curve_mul_a(t2, t2); \ + F##_add(t4, t4, t2); \ + F##_mul(t0, t1, t4); \ + F##_add(r->y, r->y, t0); \ + F##_mul(t0, t5, t4); \ + F##_mul(r->x, t3, r->x); \ + F##_sub(r->x, r->x, t0); \ + F##_mul(t0, t3, t1); \ + F##_mul(r->z, t5, r->z); \ + F##_add(r->z, r->z, t0); \ + } \ + \ + r->coord = PROJC; \ + } \ + RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } \ + RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + F##_free(t3); \ + F##_free(t4); \ + F##_free(t5); \ + } \ + } \ + +/** + * Defines a template for point addition in homogeneous projective + * coordinates. + * + * Formulas for mixed addition from + * "Complete addition formulas for prime order elliptic curves" + * by Joost Renes, Craig Costello, and Lejla Batina + * https://eprint.iacr.org/2015/1060.pdf + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#if defined(EP_MIXED) && defined(STRIP) + +#define TMPL_ADD_PROJC_IMP(C, F) \ + static void C##_add_projc_imp(C##_t r, const C##_t p, const C##_t q) { \ + /* If code size is a problem, leave only the mixed version. */ \ + C##_add_projc_mix(r, p, q); \ + } \ + +#else + +#define TMPL_ADD_PROJC_IMP(C, F) \ + static void C##_add_projc_imp(C##_t r, const C##_t p, const C##_t q) { \ + F##_t t0, t1, t2, t3, t4, t5; \ + \ + if (q->coord == BASIC) { \ + C##_add_projc_mix(r, p, q); \ + return; \ + } \ + \ + F##_null(t0); \ + F##_null(t1); \ + F##_null(t2); \ + F##_null(t3); \ + F##_null(t4); \ + F##_null(t5); \ + \ + RLC_TRY { \ + F##_new(t0); \ + F##_new(t1); \ + F##_new(t2); \ + F##_new(t3); \ + F##_new(t4); \ + F##_new(t5); \ + \ + F##_mul(t0, p->x, q->x); \ + F##_mul(t1, p->y, q->y); \ + F##_mul(t2, p->z, q->z); \ + F##_add(t3, p->x, p->y); \ + F##_add(t4, q->x, q->y); \ + F##_mul(t3, t3, t4); \ + F##_add(t4, t0, t1); \ + F##_sub(t3, t3, t4); \ + if (C##_curve_opt_a() == RLC_ZERO) { \ + /* Cost of 12M + 2m_3b + 19a. */ \ + F##_add(t4, p->y, p->z); \ + F##_add(t5, q->y, q->z); \ + F##_mul(t4, t4, t5); \ + F##_add(t5, t1, t2); \ + F##_sub(t4, t4, t5); \ + F##_add(r->y, q->x, q->z); \ + F##_add(r->x, p->x, p->z); \ + F##_mul(r->x, r->x, r->y); \ + F##_add(r->y, t0, t2); \ + F##_sub(r->y, r->x, r->y); \ + F##_dbl(r->x, t0); \ + F##_add(t0, t0, r->x); \ + F##_dbl(t5, t2); \ + F##_add(t5, t5, t2); \ + C##_curve_mul_b(t2, t5); \ + F##_add(r->z, t1, t2); \ + F##_sub(t1, t1, t2); \ + F##_dbl(t5, r->y); \ + F##_add(t5, t5, r->y); \ + C##_curve_mul_b(r->y, t5); \ + F##_mul(r->x, t4, r->y); \ + F##_mul(t2, t3, t1); \ + F##_sub(r->x, t2, r->x); \ + F##_mul(r->y, t0, r->y); \ + F##_mul(t1, t1, r->z); \ + F##_add(r->y, t1, r->y); \ + F##_mul(t0, t0, t3); \ + F##_mul(r->z, r->z, t4); \ + F##_add(r->z, r->z, t0); \ + } else if (C##_curve_opt_a() == RLC_MIN3) { \ + /* Cost of 12M + 2m_b + 29a. */ \ + F##_add(t4, p->y, p->z); \ + F##_add(t5, q->y, q->z); \ + F##_mul(t4, t4, t5); \ + F##_add(t5, t1, t2); \ + F##_sub(t4, t4, t5); \ + F##_add(r->x, p->x, p->z); \ + F##_add(r->y, q->x, q->z); \ + F##_mul(r->x, r->x, r->y); \ + F##_add(r->y, t0, t2); \ + F##_sub(r->y, r->x, r->y); \ + C##_curve_mul_b(r->z, t2); \ + F##_sub(r->x, r->y, r->z); \ + F##_dbl(r->z, r->x); \ + F##_add(r->x, r->x, r->z); \ + F##_sub(r->z, t1, r->x); \ + F##_add(r->x, t1, r->x); \ + C##_curve_mul_b(r->y, r->y); \ + F##_dbl(t1, t2); \ + F##_add(t2, t1, t2); \ + F##_sub(r->y, r->y, t2); \ + F##_sub(r->y, r->y, t0); \ + F##_dbl(t1, r->y); \ + F##_add(r->y, t1, r->y); \ + F##_dbl(t1, t0); \ + F##_add(t0, t1, t0); \ + F##_sub(t0, t0, t2); \ + F##_mul(t1, t4, r->y); \ + F##_mul(t2, t0, r->y); \ + F##_mul(r->y, r->x, r->z); \ + F##_add(r->y, r->y, t2); \ + F##_mul(r->x, t3, r->x); \ + F##_sub(r->x, r->x, t1); \ + F##_mul(r->z, t4, r->z); \ + F##_mul(t1, t3, t0); \ + F##_add(r->z, r->z, t1); \ + } else { \ + /* Cost of 12M + 3m_a + 2_m3b + 23a. */ \ + F##_add(t4, p->x, p->z); \ + F##_add(t5, q->x, q->z); \ + F##_mul(t4, t4, t5); \ + F##_add(t5, t0, t2); \ + F##_sub(t4, t4, t5); \ + F##_add(t5, p->y, p->z); \ + F##_add(r->x, q->y, q->z); \ + F##_mul(t5, t5, r->x); \ + F##_add(r->x, t1, t2); \ + F##_sub(t5, t5, r->x); \ + C##_curve_mul_a(r->z, t4); \ + F##_dbl(r->x, t2); \ + F##_add(r->x, r->x, t2); \ + C##_curve_mul_b(r->x, r->x); \ + F##_add(r->z, r->x, r->z); \ + F##_sub(r->x, t1, r->z); \ + F##_add(r->z, t1, r->z); \ + F##_mul(r->y, r->x, r->z); \ + F##_dbl(t1, t4); \ + F##_add(t1, t1, t4); \ + C##_curve_mul_b(t4, t1); \ + F##_dbl(t1, t0); \ + F##_add(t1, t1, t0); \ + C##_curve_mul_a(t2, t2); \ + F##_add(t1, t1, t2); \ + F##_sub(t2, t0, t2); \ + C##_curve_mul_a(t2, t2); \ + F##_add(t4, t4, t2); \ + F##_mul(t0, t1, t4); \ + F##_add(r->y, r->y, t0); \ + F##_mul(t0, t5, t4); \ + F##_mul(r->x, t3, r->x); \ + F##_sub(r->x, r->x, t0); \ + F##_mul(t0, t3, t1); \ + F##_mul(r->z, t5, r->z); \ + F##_add(r->z, r->z, t0); \ + } \ + r->coord = PROJC; \ + } RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + F##_free(t3); \ + F##_free(t4); \ + F##_free(t5); \ + } \ + } \ + +#endif + +/** + * Defines a template for mixed point addition in Jacobian coordinates. + * + * madd-2007-bl formulas: 7M + 4S + 9add + 1*4 + 3*2. + * http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-madd-2007-bl + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#define TMPL_ADD_JACOB_MIX(C, F) \ + static void C##_add_jacob_mix(C##_t r, const C##_t p, const C##_t q) { \ + F##_t t0, t1, t2, t3, t4, t5, t6; \ + \ + F##_null(t0); \ + F##_null(t1); \ + F##_null(t2); \ + F##_null(t3); \ + F##_null(t4); \ + F##_null(t5); \ + F##_null(t6); \ + \ + RLC_TRY { \ + F##_new(t0); \ + F##_new(t1); \ + F##_new(t2); \ + F##_new(t3); \ + F##_new(t4); \ + F##_new(t5); \ + F##_new(t6); \ + \ + if (p->coord != BASIC) { \ + /* t0 = z1^2. */ \ + F##_sqr(t0, p->z); \ + \ + /* t3 = U2 = x2 * z1^2. */ \ + F##_mul(t3, q->x, t0); \ + \ + /* t1 = S2 = y2 * z1^3. */ \ + F##_mul(t1, t0, p->z); \ + F##_mul(t1, t1, q->y); \ + \ + /* t3 = H = U2 - x1. */ \ + F##_sub(t3, t3, p->x); \ + \ + /* t1 = R = 2 * (S2 - y1). */ \ + F##_sub(t1, t1, p->y); \ + F##_dbl(t1, t1); \ + } else { \ + /* H = x2 - x1. */ \ + F##_sub(t3, q->x, p->x); \ + \ + /* t1 = R = 2 * (y2 - y1). */ \ + F##_sub(t1, q->y, p->y); \ + F##_dbl(t1, t1); \ + } \ + \ + /* t2 = HH = H^2. */ \ + F##_sqr(t2, t3); \ + \ + /* If H is zero. */ \ + if (F##_is_zero(t3)) { \ + if (F##_is_zero(t1)) { \ + /* If I is zero, p = q, should have doubled. */ \ + C##_dbl_jacob(r, p); \ + } else { \ + /* If I is not zero, q = -p, r = infinity. */ \ + C##_set_infty(r); \ + } \ + } else { \ + /* t4 = I = 4*HH. */ \ + F##_dbl(t4, t2); \ + F##_dbl(t4, t4); \ + \ + /* t5 = J = H * I. */ \ + F##_mul(t5, t3, t4); \ + \ + /* t4 = V = x1 * I. */ \ + F##_mul(t4, p->x, t4); \ + \ + /* x3 = R^2 - J - 2 * V. */ \ + F##_sqr(r->x, t1); \ + F##_sub(r->x, r->x, t5); \ + F##_dbl(t6, t4); \ + F##_sub(r->x, r->x, t6); \ + \ + /* y3 = R * (V - x3) - 2 * Y1 * J. */ \ + F##_sub(t4, t4, r->x); \ + F##_mul(t4, t4, t1); \ + F##_mul(t1, p->y, t5); \ + F##_dbl(t1, t1); \ + F##_sub(r->y, t4, t1); \ + \ + if (p->coord != BASIC) { \ + /* z3 = (z1 + H)^2 - z1^2 - HH. */ \ + F##_add(r->z, p->z, t3); \ + F##_sqr(r->z, r->z); \ + F##_sub(r->z, r->z, t0); \ + F##_sub(r->z, r->z, t2); \ + } else { \ + /* z3 = 2 * H. */ \ + F##_dbl(r->z, t3); \ + } \ + } \ + r->coord = JACOB; \ + } RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } \ + RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + F##_free(t3); \ + F##_free(t4); \ + F##_free(t5); \ + F##_free(t6); \ + } \ + } \ + +/** + * Defines a template for point addition in Jacobian coordinates. + * + * add-2007-bl formulas: 11M + 5S + 9add + 4*2 + * http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#if defined(EP_MIXED) && defined(STRIP) + +#define TMPL_ADD_JACOB_IMP(C, F) \ + static void C##_add_jacob_imp(C##_t r, const C##_t p, const C##_t q) { \ + /* If code size is a problem, leave only the mixed version. */ \ + C##_add_jacob_mix(r, p, q); \ + } \ + +#else + +#define TMPL_ADD_JACOB_IMP(C, F) \ + static void C##_add_jacob_imp(C##_t r, const C##_t p, const C##_t q) { \ + F##_t t0, t1, t2, t3, t4, t5, t6; \ + \ + if (q->coord == BASIC) { \ + C##_add_jacob_mix(r, p, q); \ + return; \ + } \ + \ + F##_null(t0); \ + F##_null(t1); \ + F##_null(t2); \ + F##_null(t3); \ + F##_null(t4); \ + F##_null(t5); \ + F##_null(t6); \ + \ + RLC_TRY { \ + F##_new(t0); \ + F##_new(t1); \ + F##_new(t2); \ + F##_new(t3); \ + F##_new(t4); \ + F##_new(t5); \ + F##_new(t6); \ + \ + /* t0 = z1^2. */ \ + F##_sqr(t0, p->z); \ + \ + /* t1 = z2^2. */ \ + F##_sqr(t1, q->z); \ + \ + /* t2 = U1 = x1 * z2^2. */ \ + F##_mul(t2, p->x, t1); \ + \ + /* t3 = U2 = x2 * z1^2. */ \ + F##_mul(t3, q->x, t0); \ + \ + /* t6 = z1^2 + z2^2. */ \ + F##_add(t6, t0, t1); \ + \ + /* t0 = S2 = y2 * z1^3. */ \ + F##_mul(t0, t0, p->z); \ + F##_mul(t0, t0, q->y); \ + \ + /* t1 = S1 = y1 * z2^3. */ \ + F##_mul(t1, t1, q->z); \ + F##_mul(t1, t1, p->y); \ + \ + /* t3 = H = U2 - U1. */ \ + F##_sub(t3, t3, t2); \ + \ + /* t0 = R = 2 * (S2 - S1). */ \ + F##_sub(t0, t0, t1); \ + F##_dbl(t0, t0); \ + \ + /* If E is zero. */ \ + if (F##_is_zero(t3)) { \ + if (F##_is_zero(t0)) { \ + /* If I is zero, p = q, should have doubled. */ \ + C##_dbl_jacob(r, p); \ + } else { \ + /* If I is not zero, q = -p, r = infinity. */ \ + C##_set_infty(r); \ + } \ + } else { \ + /* t4 = I = (2*H)^2. */ \ + F##_dbl(t4, t3); \ + F##_sqr(t4, t4); \ + \ + /* t5 = J = H * I. */ \ + F##_mul(t5, t3, t4); \ + \ + /* t4 = V = U1 * I. */ \ + F##_mul(t4, t2, t4); \ + \ + /* x3 = R^2 - J - 2 * V. */ \ + F##_sqr(r->x, t0); \ + F##_sub(r->x, r->x, t5); \ + F##_dbl(t2, t4); \ + F##_sub(r->x, r->x, t2); \ + \ + /* y3 = R * (V - x3) - 2 * S1 * J. */ \ + F##_sub(t4, t4, r->x); \ + F##_mul(t4, t4, t0); \ + F##_mul(t1, t1, t5); \ + F##_dbl(t1, t1); \ + F##_sub(r->y, t4, t1); \ + \ + /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ \ + F##_add(r->z, p->z, q->z); \ + F##_sqr(r->z, r->z); \ + F##_sub(r->z, r->z, t6); \ + F##_mul(r->z, r->z, t3); \ + } \ + r->coord = JACOB; \ + } RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + F##_free(t3); \ + F##_free(t4); \ + F##_free(t5); \ + F##_free(t6); \ + } \ + } \ + + #endif \ No newline at end of file diff --git a/src/tmpl/relic_tmpl_map.h b/src/tmpl/relic_ep_map_tmpl.h similarity index 98% rename from src/tmpl/relic_tmpl_map.h rename to src/tmpl/relic_ep_map_tmpl.h index 2caaef1f7..d5d06b40e 100644 --- a/src/tmpl/relic_tmpl_map.h +++ b/src/tmpl/relic_ep_map_tmpl.h @@ -24,7 +24,7 @@ /** * @file * - * Templates for hashing to elliptic curves. + * Template for hashing to prime elliptic curves. * * @ingroup tmpl */ @@ -34,7 +34,7 @@ /*============================================================================*/ /** - * Evaluate a polynomial represented by its coefficients over a using Horner's + * Evaluates a polynomial represented by its coefficients over a using Horner's * rule. Might promove to an API if needed elsewhere in the future. */ #define TMPL_MAP_HORNER(PFX, IN) \