Skip to content

Commit

Permalink
Merge pull request #276 from relic-toolkit/fm16
Browse files Browse the repository at this point in the history
Add support to pairing-friendly curves from family Fotiadis-Martindale with embedding degree 16.
  • Loading branch information
dfaranha authored Nov 10, 2023
2 parents e5c6d38 + 5aa9c1b commit 2ad2164
Show file tree
Hide file tree
Showing 18 changed files with 536 additions and 82 deletions.
4 changes: 4 additions & 0 deletions include/relic_ep.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ enum {
EP_B12,
/* New family from Fotiadis-Martindale family with embedding degree 16. */
EP_N16,
/* Fotiadis-Martindale famile with embedding degree 16. */
EP_FM16,
/* Kachisa-Schaefer-Scott family with embedding degree 16. */
EP_K16,
/* Fotiadis-Martindale family with embedding degree 18. */
Expand Down Expand Up @@ -175,6 +177,8 @@ enum {
SG18_P638,
/** New family with embeeding degree 16. */
N16_P765,
/* Fotiadis-Moartindale with embedding degree 16. */
FM16_P765,
/** Kachisa-Schaefer-Scott with embedding degree 16. */
K16_P766,
/** 1536-bit supersingular curve. */
Expand Down
2 changes: 2 additions & 0 deletions include/relic_fp.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ enum {
SG18_638,
/** 765-bit prime for new family with embedding degree 16. */
N16_765,
/** 765-bit prime for FM curve with embeddind degree 16. */
FM16_765,
/** 766-bit prime for KSS curve with embedding degree 16. */
K16_766,
/** 1024-bit prime for CTIDH. */
Expand Down
221 changes: 149 additions & 72 deletions src/ep/relic_ep_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,12 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
/* enough space for two field elements plus extra bytes for uniformity */
const size_t len_per_elm = (FP_PRIME + ep_param_level() + 7) / 8;
uint8_t s, *pseudo_random_bytes = RLC_ALLOCA(uint8_t, 2 * len_per_elm + 1);
fp_t c, t, u, v, w, y, x1, y1, z1;
fp_t a, c, t, u, v, w, y, x1, y1, z1;
ctx_t *ctx = core_get();
bn_t k;

bn_null(k);
fp_null(a);
fp_null(c);
fp_null(t);
fp_null(u);
Expand Down Expand Up @@ -276,77 +277,153 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
fp_prime_conv(t, k);
s = pseudo_random_bytes[2 * len_per_elm] & 1;

fp_copy(a, ep_curve_get_a());

if ((ep_curve_opt_b() == RLC_ZERO) && (ctx->mod8 == 1)) {
/* This is the approach due to Koshelev introduced in
* https://eprint.iacr.org/2021/1034.pdf */

/* Compute t^2 = 3c*sqrt(a)*(2c^3*x^6 - 3*c^2*x^4 - 3*c*x^2 + 2).*/
/* Compute w = 3*c. */
fp_set_dig(c, -fp_prime_get_qnr());
fp_neg(c, c);
fp_dbl(w, c);
fp_add(w, w, c);

/* Compute x^2, x^4 and x^6 in sequence. */
fp_sqr(z1, u);
fp_sqr(y1, z1);
fp_mul(t, z1, y1);

fp_dbl(t, t);
fp_mul(t, t, c);
fp_mul(t, t, c);
fp_mul(t, t, c);

fp_mul(v, y1, c);
fp_mul(v, v, w);
fp_sub(t, t, v);

/* v = -3*c*x^2. */
fp_mul(v, w, z1);
fp_neg(v, v);
fp_add(t, t, v);
fp_add_dig(t, t, 2);

/* Assume a = 1 for simplicitly. */
fp_mul(t, t, w);
fp_mul(t, t, ctx->ep_map_c[6]);
dig_t c1 = fp_is_sqr(t);
/* If t is not square, compute u = 1/(uc), t = sqrt(t/c)/(c*u^3)*/
fp_inv(v, c);
fp_inv(x1, u);
fp_mul(y1, t, v);
/* If t is a square, extract its square root. */
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);
fp_srt(t, t);
fp_mul(y1, t, v);
fp_sqr(y, x1);
fp_mul(y, y, x1);
fp_mul(y1, y1, y);
fp_mul(x1, x1, v);
dv_copy_cond(u, x1, RLC_FP_DIGS, !c1);
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);

/* Compute x = sqrt(a)*(c*x^2 - 2)/(-3*c*x^2). */
fp_sqr(z1, u);
fp_mul(v, w, z1);
fp_neg(v, v);
fp_inv(v, v);
fp_mul(p->x, z1, c);
fp_sub_dig(p->x, p->x, 2);
fp_mul(p->x, p->x, v);
fp_mul(p->x, p->x, ctx->ep_map_c[6]);

/* Compute y = y*2*sqrt(a)/(3^2*c^2*x^3). */
fp_mul(z1, z1, u);
fp_sqr(w, w);
fp_mul(w, w, z1);
fp_inv(w, w);
fp_dbl(p->y, ctx->ep_map_c[6]);
fp_mul(p->y, p->y, t);
fp_mul(p->y, p->y, w);
fp_set_dig(p->z, 1);
p->coord = BASIC;
ep_mul_cof(p, p);
if (fp_is_sqr(a)) {
/* Compute t^2 = 3c*sqrt(a)*(2c^3*x^6 - 3*c^2*x^4 - 3*c*x^2 + 2).*/
/* Compute w = 3*c. */
fp_set_dig(c, -fp_prime_get_qnr());
fp_neg(c, c);
fp_dbl(w, c);
fp_add(w, w, c);

/* Compute x^2, x^4 and x^6 in sequence. */
fp_sqr(z1, u);
fp_sqr(y1, z1);
fp_mul(t, z1, y1);

fp_dbl(t, t);
fp_mul(t, t, c);
fp_mul(t, t, c);
fp_mul(t, t, c);

fp_mul(v, y1, c);
fp_mul(v, v, w);
fp_sub(t, t, v);

/* v = -3*c*x^2. */
fp_mul(v, w, z1);
fp_neg(v, v);
fp_add(t, t, v);
fp_add_dig(t, t, 2);

/* Assume a = 1 for simplicitly. */
fp_mul(t, t, w);
fp_mul(t, t, ctx->ep_map_c[6]);
dig_t c1 = fp_is_sqr(t);
/* If t is not square, compute u = 1/(uc), t = sqrt(t/c)/(c*u^3)*/
fp_inv(v, c);
fp_inv(x1, u);
fp_mul(y1, t, v);
/* If t is a square, extract its square root. */
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);
fp_srt(t, t);
fp_mul(y1, t, v);
fp_sqr(y, x1);
fp_mul(y, y, x1);
fp_mul(y1, y1, y);
fp_mul(x1, x1, v);
dv_copy_cond(u, x1, RLC_FP_DIGS, !c1);
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);

/* Compute x = sqrt(a)*(c*x^2 - 2)/(-3*c*x^2). */
fp_sqr(z1, u);
fp_mul(v, w, z1);
fp_neg(v, v);
fp_inv(v, v);
fp_mul(p->x, z1, c);
fp_sub_dig(p->x, p->x, 2);
fp_mul(p->x, p->x, v);
fp_mul(p->x, p->x, ctx->ep_map_c[6]);

/* Compute y = y*2*sqrt(a)/(3^2*c^2*x^3). */
fp_mul(z1, z1, u);
fp_sqr(w, w);
fp_mul(w, w, z1);
fp_inv(w, w);
fp_dbl(p->y, ctx->ep_map_c[6]);
fp_mul(p->y, p->y, t);
fp_mul(p->y, p->y, w);
fp_set_dig(p->z, 1);
p->coord = BASIC;
} else {
/* Compute c = 3*a^2, t^2 = 6a(9u^5 − 14au^3 + 3cu).*/
fp_neg(a, a);
fp_sqr(c, a);
fp_dbl(t, c);
fp_add(c, c, t);
fp_dbl(t, c);
fp_add(t, t, c);
fp_mul(t, t, u);

fp_sqr(v, u);
fp_mul(w, v, u);
fp_mul(x1, w, a);
fp_mul_dig(x1, x1, 14);
fp_sub(t, t, x1);

fp_mul(w, w, v);
fp_dbl(x1, w);
fp_add(w, w, x1);
fp_dbl(x1, w);
fp_add(w, w, x1);
fp_add(t, t, w);
fp_mul(t, t, a);
fp_dbl(t, t);
fp_dbl(x1, t);
fp_add(t, t, x1);
dig_t c1 = fp_is_sqr(t);
/* If t is not square, compute u = a/u, t = a*sqrt(a*t)/u^3*/
fp_inv(x1, u);
fp_mul(y1, t, a);
/* If t is a square, extract its square root. */
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);
fp_srt(t, t);
fp_mul(y1, t, a);
fp_sqr(y, x1);
fp_mul(y, y, x1);
fp_mul(y1, y1, y);
fp_mul(x1, x1, a);
dv_copy_cond(u, x1, RLC_FP_DIGS, !c1);
dv_copy_cond(t, y1, RLC_FP_DIGS, !c1);

/* Compute x = 2^4*i*3*a^2*u / (3*(3*u^2 - a))^2. */
fp_copy(y, ctx->ep_map_c[6]);
fp_mul(c, c, u);
fp_mul(x1, c, y);
fp_dbl(x1, x1);
fp_dbl(x1, x1);
fp_dbl(x1, x1);
fp_dbl(p->x, x1);
fp_sqr(v, u);
fp_dbl(z1, v);
fp_add(z1, z1, v);
fp_sub(z1, z1, a);
fp_dbl(p->z, z1);
fp_add(p->z, p->z, z1);

/* Compute y = 3*2*(i-1)*a*(3^2*u^2 + a)*t / (3*(3*u^2 - a))^3. */
fp_sub_dig(y, y, 1);
fp_mul(y1, y, a);
fp_dbl(y1, y1);
fp_dbl(p->y, y1);
fp_add(p->y, p->y, y1);
fp_mul(p->y, p->y, t);
fp_dbl(y1, v);
fp_add(y1, y1, v);
fp_dbl(v, y1);
fp_add(y1, y1, v);
fp_add(y1, y1, a);
fp_mul(p->y, p->y, y1);

/* Multiply by cofactor. */
p->coord = JACOB;
ep_norm(p, p);
}
} else if ((ep_curve_opt_b() == RLC_ZERO) && (ctx->mod8 != 1)) {
/* This is the approach due to Koshelev introduced in
* https://eprint.iacr.org/2021/1604.pdf */
Expand Down Expand Up @@ -435,7 +512,6 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
fp_mul(c, ctx->ep_map_c[5], x1);
fp_copy(p->x, v);
fp_sqr(p->y, y);
p->coord = BASIC;
/* We use zp as temporary, but there is no problem with \psi. */
int index = 0;
fp_copy(y1, u);
Expand Down Expand Up @@ -486,9 +562,8 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
fp_mul(z1, z1, y);
dv_copy_cond(p->x, t, RLC_FP_DIGS, c3);
dv_copy_cond(p->y, z1, RLC_FP_DIGS, c3);
/* Multiply by cofactor. */
p->coord = BASIC;
fp_set_dig(p->z, 1);
ep_mul_cof(p, p);
} else {
/* This is the SwiftEC case per se. */
if (ep_curve_opt_a() != RLC_ZERO) {
Expand Down Expand Up @@ -555,16 +630,18 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) {
fp_copy(p->y, t);
fp_set_dig(p->z, 1);
p->coord = BASIC;
ep_mul_cof(p, p);
}
}
}
/* Multiply by cofactor. */
ep_mul_cof(p, p);
}
RLC_CATCH_ANY {
RLC_THROW(ERR_CAUGHT);
}
RLC_FINALLY {
bn_free(k);
fp_free(a);
fp_free(c);
fp_free(t);
fp_free(u);
Expand Down
20 changes: 19 additions & 1 deletion src/ep/relic_ep_mul_cof.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void ep_mul_cof(ep_t r, const ep_t p) {
}
break;
case EP_N16:
/* if (u % 2) == 0, compute = (u * (u**3+1)//2)*P
/* if (u % 2) == 0, compute = (u * (u**3+1)/2)*P
* else Compute (u * (u**3+1))*P */
fp_prime_get_par(k);
bn_sqr(l, k);
Expand All @@ -87,6 +87,24 @@ void ep_mul_cof(ep_t r, const ep_t p) {
ep_mul_basic(r, p, k);
}
break;
case EP_FM16:
/* Compute (u/2)*P + [u^3]*phi([u/2]P) */
fp_prime_get_par(k);
bn_sqr(l, k);
bn_mul(l, l, k);
if (bn_is_even(k)) {
bn_hlv(k, k);
}
if (bn_bits(k) < RLC_DIG) {
ep_mul_dig(r, p, k->dp[0]);
} else {
ep_mul_basic(r, p, k);
}
ep_psi(v, r);
ep_mul_basic(v, v, l);
ep_add(r, r, v);
ep_norm(r, r);
break;
case EP_K16:
/* Compute 1250*(P + [(u+1)/2]phi(P)) */
fp_prime_get_par(k);
Expand Down
Loading

0 comments on commit 2ad2164

Please sign in to comment.