Skip to content

Commit

Permalink
Merge pull request #283 from relic-toolkit/fm18
Browse files Browse the repository at this point in the history
Merge Fotiadis-Martindale curves with embedding degree 18.
  • Loading branch information
dfaranha authored Dec 9, 2023
2 parents 1b36887 + ab3f2f3 commit 6a01d9a
Show file tree
Hide file tree
Showing 13 changed files with 296 additions and 39 deletions.
4 changes: 2 additions & 2 deletions include/relic_pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
#elif FP_PRIME == 315 || FP_PRIME == 317 || FP_PRIME == 330 || FP_PRIME == 509 || FP_PRIME == 765 || FP_PRIME == 766
#define RLC_G2_LOWER ep4_
#define RLC_G2_BASEF(A) A[0][0]
#elif FP_PRIME == 508 || FP_PRIME == 638 && !defined(FP_QNRES)
#elif FP_PRIME == 508 || FP_PRIME == 768 || FP_PRIME == 638 && !defined(FP_QNRES)
#define RLC_G2_LOWER ep3_
#define RLC_G2_BASEF(A) A[0]
#else
Expand All @@ -78,7 +78,7 @@
#elif FP_PRIME == 315 || FP_PRIME == 317 || FP_PRIME == 509
#define RLC_GT_LOWER fp24_
#define RLC_GT_EMBED 24
#elif FP_PRIME == 508 || FP_PRIME == 638 && !defined(FP_QNRES)
#elif FP_PRIME == 508 || FP_PRIME == 768 || FP_PRIME == 638 && !defined(FP_QNRES)
#define RLC_GT_LOWER fp18_
#define RLC_GT_EMBED 18
#elif FP_PRIME == 330 || FP_PRIME == 765 || FP_PRIME == 766
Expand Down
4 changes: 4 additions & 0 deletions src/ep/relic_ep_param.c
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,9 @@ void ep_param_print(void) {
case K16_P766:
util_banner("Curve K16-P766:", 0);
break;
case FM18_P768:
util_banner("Curve FM18-P768:", 0);
break;
case SS_P1536:
util_banner("Curve SS-P1536:", 0);
break;
Expand Down Expand Up @@ -1818,6 +1821,7 @@ int ep_param_level(void) {
case N16_P765:
case FM16_P765:
case K16_P766:
case FM18_P768:
case K18_P638:
case B24_P509:
return 192;
Expand Down
18 changes: 9 additions & 9 deletions src/epx/relic_ep3_curve.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@
#define FM18_P768_A0 "0"
#define FM18_P768_A1 "0"
#define FM18_P768_A2 "0"
#define FM18_P768_B0 "0"
#define FM18_P768_B0 "-14"
#define FM18_P768_B1 "5"
#define FM18_P768_B2 "0"
#define FM18_P768_X0 "FE31E13463CB8897FE1708543815C50C0FFBC6AAE7360ACF2B36B64FC0D806FDF4B80FCFCD28CA748F6964B9C7848882AA1DEC9640D8CF09344B95F78E4E85F790959CE583A201FCAD217D3E39CADBE3B7B3F9BC0AE6E7753FA806880660B538"
#define FM18_P768_X1 "E69ECCB9020052A03987AFA34E9F30D7298AA8E02B157866C37A84B444775BF7A439E5A3BD611738444BF7DF8237B478D6A284A7D46736BC29528A88C6CE23E997AABA613211A42D027D83AFEC558BD69FDCCBEEE7273F335E449FAD8E4B1F92"
#define FM18_P768_X2 "F21BA095672FE95B02E5C5CD933F403D9C48FC980D378FC5184893E8D3E34834B32BA9D1B7A540A102EF345CA0C7E4B134F925948FA4BB3EB00184FD829FA8553EE43938E783687A553F3E75851E6B2C039698C77899D849AB8016BF9041AFC2"
#define FM18_P768_Y0 "D16A99C5ED5D491EA7B51110063533ABCC26EC4C77232489F82F04A862F9C7FCF9672EFE6960F5A2D11FABFCBBE1499F79373324699E557280FE3A588B8DEC2FB6A5376172179DA428BBECAC45F245747DD2D47D0A014119FA441326A50765F4"
#define FM18_P768_Y1 "D009FDA9F7B1666F00A9DDBAA872AA0FFD60F9436E9DFED25AE3FEF0D346C232E8B25624106D30CA7A22986423D922A1C1291D370369826DC1E189A489581191C66F1E983521C3318A66FFCA874EB12A07CAF39048C9E985C6068C7571FF6790"
#define FM18_P768_Y2 "6FAD5BE9CBC44355D5745ABB148D5132DDBBF1BEAB092D03954FD7DB16D0EC25C1EDA664057E758481AF124666DD668478B452C43B9C1B78602193262DD9AE8DD749F40F58FC458D6CF1CD3442C2822A5C976D4195276A5FC19E16759DAD1FE3"
#define FM18_P768_R "FFFFFFF27FA00045F4380E5F9EE3795E88D88C72E7B408B61E4CA1FB2558E7C336F40FAAEC98807AF3600C06C0300001"
#define FM18_P768_H "FFFFFFBC7E20087CAA5905F0B82ABB93AF7E81A53882226042648999C855F369B72CECF33CAFCEE57D8E28C84A08805B59DE451E30AC535A4DD982BCD28F9915B40B200C183FEEB08DC7E199BD1C0BC98FB2653657500B21B5876AA05AA4870EF344801BFE0329F91259BB407D680660A83C30FD7B152124C532AE9C1834BB5967AA84FD428CC94EDE0BBF89981839AC28D48E78F22A4695C2C0CC996FFAF415B9B684B1B2427CAA3EE14D0B8463A431ACC81B81F156C21F6B157D8BE3DCB1E0459DE473AC6EFAF4BD9EBBC861C799A4F9EF7D445FB243587315E11A04E4BF85CBE901BA1273F2C229293D5102400004"
#define FM18_P768_X0 "1D930B0B04D7465AB78CA64B2B5DC31F76CA89CABAF298299A7A9F372BD3FF506AC99CB9BE1915BA02C7ED843B32E5B7117F4FF177B9F8EA8E917EA292C020ABF01B8EC7702797F46657A4AC50E0B1BC0E3EFAB4668822FC41DAA3E3E4B54361"
#define FM18_P768_X1 "EC814ED9C93EB3787C1D58406920E3941BF9B39200431A5DD3114F3E9A8202CCCA742B4D0A96D083D11883E4CD4A5AA2FF3D10CAFF789D754C4AF11C09BD453FF379F07C778CFDE0156B87B8A731DD5998715486EBFA0A0F40A7591AC19AF918"
#define FM18_P768_X2 "FCDA64C5662F0E0F0A1FCDCC80BBDCC4B99BAEB06917E0BE604828C636927F9A08A40C184490CE3E5982EDECD2E9D0F93A97BCE43E3C05EC502E781C47866BE70B51F542027C96A2090E96B6428177465C4645F5808ECCDA5A0CB34F689F0E7E"
#define FM18_P768_Y0 "51CC2E24BFC22B4D46B33FF63B91D0B6EF6CDAF5AEFA9B54588F08787362B29489CD18D3EDEEF975B3E07090149EFEEC95455CBD7FADAC43284D4836A2581F81214FF8D7273AA46DF440628B1B4AEBE2BD30809C675EC62B365DE91484BAA6D8"
#define FM18_P768_Y1 "87A1EEC340AB26B14EBE6F2056CE339553090C95A0653432428B62FE34BCCA238F0D067B8E8F2345BC2F46DE68493C75C2ED07C5F2D9B29A6BF9FA730D1C78582819735D7FED671B03C359DECC81765A8A8E1DD16C87801FC3FC40176FB55C5C"
#define FM18_P768_Y2 "DFE9CABA0A20C5FB26091329C60716EC027B828A173120F1AC7BAA5336E97348B26071A022DC0352074F0EA581F63632B6BBBBE9F06CE2762F66087D50D7DB9C96B0192E30F4406104F5D53DCC922A40AEA7600FD79AFB7E2A83350A4D0AD74A"
#define FM18_P768_R "FFFFFFF27FA00045F4380E5F9EE3795E88D88C72E7B408B61E4CA1FB2558E7C336F40FAAEC98807AF3600C06C0300001"
#define FM18_P768_H "FFFFFFBC7E20087CAA5905F0B82ABB93AF7E81A53882226042648999C855F369B72CECF33CAFCEE57D8E28C84A08805B59DE451E30AC535A4DD982BCD28F9915B40B200C183FEEB08DC7E199BD1C0BC98FB2653657500B21B5876AA05AA4870EF344801BFE0329F91259BB407D680660A83C30FD7B152124C532AE9C1834BB5967AA84FD428CC94EDE0BBF89981839AB28D48E93F2EA45539030933B28949C5EA287BBE39E92B7641ABED52EC449C1F8561BF845845AF977FFF07688C87D2320CF7D4DDBA602142190F32D2FCD0DFB975E2FF266BD2130ABC252AC90AFF19B742F92924F46054CE84DB1865E82A00003"
/** @} */
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/epx/relic_ep3_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ static void ep3_psi(ep3_t r, const ep3_t p) {
ep3_frb(r, r, 1);
break;
case EP_FM18:
/* For FM18, we have that -u = (p-p^4) mod r. */
/* For FM18, we have that u = (p^4-p) mod r. */
ep3_frb(q, p, 3);
ep3_sub(r, p, q);
ep3_sub(r, q, p);
ep3_frb(r, r, 1);
break;
}
Expand Down
84 changes: 84 additions & 0 deletions src/epx/relic_ep3_mul_cof.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ static void ep3_mul_cof_k18(ep3_t r, const ep3_t p) {
ep3_dbl(t4, t4);
/* r = [5u+18, u^3+3u^2+1, -3u^2-8u, -3u+1, -u^2-2, u^2+5u]. */
ep3_add(r, t4, t3);
ep3_norm(r, r);
} RLC_CATCH_ANY {
RLC_THROW(ERR_CAUGHT);
} RLC_FINALLY {
Expand Down Expand Up @@ -202,6 +203,86 @@ static void ep3_mul_cof_sg18(ep3_t r, const ep3_t p) {
ep3_dbl(t4, t0);
ep3_frb(t4, t4, 3);
ep3_sub(r, t3, t4);
ep3_norm(r, r);
} RLC_CATCH_ANY {
RLC_THROW(ERR_CAUGHT);
} RLC_FINALLY {
ep3_free(t0);
ep3_free(t1);
ep3_free(t2);
ep3_free(t3);
ep3_free(t4);
bn_free(x);
}
}

/**
* Multiplies a point by the cofactor in a Fotiadis-Mardindale curve.
*
* @param[out] r - the result.
* @param[in] p - the point to multiply.
*/
static void ep3_mul_cof_fm18(ep3_t r, const ep3_t p) {
ep3_t t0, t1, t2, t3, t4;
bn_t x;

ep3_null(t0);
ep3_null(t1);
ep3_null(t2);
ep3_null(t3);
ep3_null(t4);
bn_null(x);

RLC_TRY {
ep3_new(t0);
ep3_new(t1);
ep3_new(t2);
ep3_new(t3);
ep3_new(t4);
bn_new(x);

/* Vector computed by Guillevic's MAGMA script:
[2*x*(x+2)/3, x^3-(x+2)/3, -2*x^2*(x+2)/3, -x*(x^3+(x+2)/3), 2*(x+2)/3, x^2*(x^3+(x+2)/3)-1] */
fp_prime_get_par(x);

/* t0 = [(x+2)/3]P, t1 = [x]P. */
bn_add_dig(x, x, 2);
bn_div_dig(x, x, 3);
ep3_mul_basic(t0, p, x);
ep3_dbl(t1, t0);
ep3_add(t1, t1, t0);
ep3_dbl(t2, p);
ep3_sub(t1, t1, t2);

/* Compute t2 = [x*(x+2)/3]P, t1 = [3*x*(x+2)/3-2x]P = [x^2]P. */
fp_prime_get_par(x);
ep3_frb(t3, t0, 4);
ep3_mul_basic(t2, t0, x);
ep3_add(t3, t3, t2);
ep3_dbl(t4, t2);
ep3_add(t4, t4, t2);
ep3_dbl(t1, t1);
ep3_sub(t1, t4, t1);
ep3_norm(t1, t1);
/* Compute t2 = [x^2*(x+2)/3]P, */
ep3_mul_basic(t2, t2, x);
ep3_frb(t4, t2, 2);
ep3_sub(t3, t3, t4);
ep3_dbl(t3, t3);
ep3_mul_basic(t2, t1, x);
ep3_sub(t4, t2, t0);
ep3_frb(t4, t4, 1);
ep3_add(t3, t3, t4);
ep3_add(t4, t2, t0);
ep3_norm(t4, t4);
ep3_mul_basic(t2, t4, x);
ep3_frb(t4, t2, 3);
ep3_sub(t3, t3, t4);
ep3_mul_basic(t2, t2, x);
ep3_sub(t2, t2, p);
ep3_frb(t2, t2, 5);
ep3_add(t3, t3, t2);
ep3_norm(r, t3);
} RLC_CATCH_ANY {
RLC_THROW(ERR_CAUGHT);
} RLC_FINALLY {
Expand Down Expand Up @@ -231,6 +312,9 @@ void ep3_mul_cof(ep3_t r, const ep3_t p) {
case EP_SG18:
ep3_mul_cof_sg18(r, p);
break;
case EP_FM18:
ep3_mul_cof_fm18(r, p);
break;
default:
/* Now, multiply by cofactor to get the correct group. */
ep3_curve_get_cof(k);
Expand Down
7 changes: 6 additions & 1 deletion src/fpx/relic_fp3_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void fp3_mul_nor(fp3_t c, const fp3_t a) {
fp3_mul_art(t, a);

int cnr = fp3_field_get_cnr();
cnr = (cnr < 0 ? -cnr : cnr);
switch (fp_prime_get_mod18()) {
case 1:
case 7:
Expand All @@ -202,7 +203,11 @@ void fp3_mul_nor(fp3_t c, const fp3_t a) {
}
cnr = cnr >> 1;
}
fp3_add(t, t, u);
if (fp3_field_get_cnr() > 0) {
fp3_add(t, t, u);
} else {
fp3_sub(t, t, u);
}
}
break;
}
Expand Down
41 changes: 26 additions & 15 deletions src/fpx/relic_fpx_cyc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1557,21 +1557,32 @@ static void fp18_gls(fp18_t c, const fp18_t a) {
RLC_TRY {
fp18_new(b);

if (ep_curve_is_pairf() == EP_SG18) {
/* -3*u = (2*p^2 - p^5) mod r */
fp18_frb(b, a, 5);
fp18_inv_cyc(b, b);
fp18_frb(c, a, 2);
fp18_sqr_cyc(c, c);
fp18_mul(c, c, b);
} else {
/* For KSS18, we have that x = p^4 - 3*p = (p^3 - 3)p mod n. */
fp18_sqr_cyc(b, a);
fp18_mul(b, b, a);
fp18_frb(c, a, 3);
fp18_inv_cyc(b, b);
fp18_mul(c, c, b);
fp18_frb(c, c, 1);
switch (ep_curve_is_pairf()) {
case EP_SG18:
/* -3*u = (2*p^2 - p^5) mod r */
fp18_frb(b, a, 5);
fp18_inv_cyc(b, b);
fp18_frb(c, a, 2);
fp18_sqr_cyc(c, c);
fp18_mul(c, c, b);
break;
case EP_K18:
/* For KSS18, we have that x = p^4 - 3*p = (p^3 - 3)p mod n. */
fp18_sqr_cyc(b, a);
fp18_mul(b, b, a);
fp18_frb(c, a, 3);
fp18_inv_cyc(b, b);
fp18_mul(c, c, b);
fp18_frb(c, c, 1);
break;
case EP_FM18:
/* For FM18, we have that u = (p^4-p) mod r. */
fp18_frb(b, a, 3);
fp18_inv_cyc(b, b);
fp18_mul(c, a, b);
fp18_frb(c, c, 1);
fp18_inv_cyc(c, c);
break;
}
}
RLC_CATCH_ANY {
Expand Down
5 changes: 3 additions & 2 deletions src/fpx/relic_fpx_field.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ int fp3_field_get_cnr() {
} else {
return 3;
}
#elif FP_PRIME == 768
return -4;
#endif

return core_get()->cnr3;
}

Expand Down Expand Up @@ -188,7 +189,7 @@ void fp3_field_init(void) {
fp_zero(t0[2]);
/* If it does not work, attempt (u + 1), otherwise double. */
/* This code will fail if p \neq 1 mod 8 because square root in Fp^3
* relic on Frobenius. Must implement explicit test for those cases. */
* relies on Frobenius. Must implement explicit test for those cases. */
if (fp3_srt(t1, t0)) {
ctx->cnr3 = 1;
fp_set_dig(t0[0], ctx->cnr3);
Expand Down
7 changes: 6 additions & 1 deletion src/low/easy/relic_fpx_add_low.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ void fp3_nord_low(dv3_t c, dv3_t a) {
dv_copy(t[1], a[0], 2 * RLC_FP_DIGS);

int cnr = fp3_field_get_cnr();
cnr = (cnr < 0 ? -cnr : cnr);
switch (fp_prime_get_mod18()) {
case 1:
case 7:
Expand All @@ -320,7 +321,11 @@ void fp3_nord_low(dv3_t c, dv3_t a) {
}
cnr = cnr >> 1;
}
fp3_addc_low(t, t, u);
if (fp3_field_get_cnr() > 0) {
fp3_addc_low(t, t, u);
} else {
fp3_subc_low(t, t, u);
}
}
break;
}
Expand Down
24 changes: 17 additions & 7 deletions src/pc/relic_pc_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void gt_rand(gt_t a) {
pp_exp_k24(a, a);
#elif FP_PRIME == 330 || FP_PRIME == 765 || FP_PRIME == 766
pp_exp_k16(a, a);
#elif FP_PRIME == 508 || FP_PRIME == 638 && !defined(FP_QNRES)
#elif FP_PRIME == 508 || FP_PRIME == 768 || FP_PRIME == 638 && !defined(FP_QNRES)
pp_exp_k18(a, a);
#else
pp_exp_k12(a, a);
Expand Down Expand Up @@ -292,6 +292,7 @@ int g2_is_valid(const g2_t a) {
g2_new(v);
g2_new(w);

fp_prime_get_par(n);
switch (ep_curve_is_pairf()) {
#if defined(EP_ENDOM) && !defined(STRIP)
/* Formulas from "Co-factor clearing and subgroup membership
Expand Down Expand Up @@ -319,7 +320,6 @@ int g2_is_valid(const g2_t a) {
* https://eprint.iacr.org/2022/348.pdf */
case EP_BN:
/*Check that [z+1]P+[z]\psi(P)+[z]\psi^2(P)=[2z]\psi^3(P)*/
fp_prime_get_par(n);
g2_mul_any(u, a, n);
g2_frb(v, u, 1);
g2_add(u, u, a);
Expand All @@ -333,7 +333,6 @@ int g2_is_valid(const g2_t a) {
/* If u is even, check that [u*p^3]P = P
* else check [p^5]P = [u]P. */
case EP_N16:
fp_prime_get_par(n);
g2_mul_any(u, a, n);
if (bn_is_even(n)) {
g2_frb(v, u, 3);
Expand All @@ -348,7 +347,6 @@ int g2_is_valid(const g2_t a) {
* https://eprint.iacr.org/2022/348.pdf
* Paper has u = 45 mod 70, we ran their code for u = 25 mod 70. */
case EP_K16:
fp_prime_get_par(n);
bn_mod_dig(&rem, n, 70);
if (rem == 45) {
bn_neg(n, n);
Expand Down Expand Up @@ -400,14 +398,12 @@ int g2_is_valid(const g2_t a) {
break;
case EP_FM16:
/* Check that u*Q == psi(Q). */
fp_prime_get_par(n);
g2_mul_any(u, a, n);
g2_frb(v, a, 1);
r = g2_on_curve(a) && (g2_cmp(u, v) == RLC_EQ);
break;
case EP_K18:
/* Check that P + u*psi2P + 2*psi3P == \mathcal{O}. */
fp_prime_get_par(n);
g2_frb(u, a, 2);
g2_frb(v, u, 1);
g2_dbl(v, v);
Expand All @@ -416,9 +412,15 @@ int g2_is_valid(const g2_t a) {
g2_neg(u, v);
r = g2_on_curve(a) && (g2_cmp(u, a) == RLC_EQ);
break;
case EP_FM18:
/* Check that Q == -u*\psi^2(Q). */
bn_neg(n, n);
g2_mul_any(u, a, n);
g2_frb(u, u, 2);
r = g2_on_curve(a) && (g2_cmp(u, a) == RLC_EQ);
break;
case EP_SG18:
/* Check that 3u*P + 2\psi^2(P) == \psi^5P] and [3]P \eq O. */
fp_prime_get_par(n);
bn_mul_dig(n, n, 3);
g2_mul_any(u, a, n);
r = g2_is_infty(a) == 0;
Expand Down Expand Up @@ -611,6 +613,14 @@ int gt_is_valid(const gt_t a) {
r = (gt_cmp(u, a) == RLC_EQ);
r &= fp18_test_cyc((void *)a);
break;
case EP_FM18:
/* Check that Q == -u*\psi^2(Q). */
bn_neg(n, n);
gt_exp(u, a, n);
gt_frb(u, u, 2);
r = (gt_cmp(u, a) == RLC_EQ);
r &= fp18_test_cyc((void *)a);
break;
case EP_SG18:
/* Check that 3u*P + 2\psi^2(P) == \psi^5P] and [3]P \eq O. */
fp_prime_get_par(n);
Expand Down
Loading

0 comments on commit 6a01d9a

Please sign in to comment.