diff --git a/.github/workflows/gmp-sec.yml b/.github/workflows/gmp-sec.yml index 61fd18203..5a2ad6c1a 100644 --- a/.github/workflows/gmp-sec.yml +++ b/.github/workflows/gmp-sec.yml @@ -61,6 +61,7 @@ jobs: gcc cmake gmp + gmp-devel update: true - name: Run CMake (MingW) diff --git a/.github/workflows/gmp.yml b/.github/workflows/gmp.yml index 03cbf8d5a..40d036ecf 100644 --- a/.github/workflows/gmp.yml +++ b/.github/workflows/gmp.yml @@ -61,6 +61,7 @@ jobs: gcc cmake gmp + gmp-devel update: true - name: Run CMake (MingW) diff --git a/bench/bench_dv.c b/bench/bench_dv.c index 7f1584619..62670d21c 100644 --- a/bench/bench_dv.c +++ b/bench/bench_dv.c @@ -67,16 +67,16 @@ static void copy(void) { BENCH_ADD(dv_copy(a, b, RLC_DV_DIGS)); } BENCH_END; - BENCH_RUN("dv_copy_cond") { + BENCH_RUN("dv_copy_sec") { rand_bytes((uint8_t *)a, RLC_DV_DIGS * sizeof(dig_t)); rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); - BENCH_ADD(dv_copy_cond(a, b, RLC_DV_DIGS, 1)); + BENCH_ADD(dv_copy_sec(a, b, RLC_DV_DIGS, 1)); } BENCH_END; - BENCH_RUN("dv_swap_cond") { + BENCH_RUN("dv_swap_sec") { rand_bytes((uint8_t *)a, RLC_DV_DIGS * sizeof(dig_t)); rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); - BENCH_ADD(dv_swap_cond(a, b, RLC_DV_DIGS, 1)); + BENCH_ADD(dv_swap_sec(a, b, RLC_DV_DIGS, 1)); } BENCH_END; BENCH_RUN("dv_cmp") { @@ -85,10 +85,10 @@ static void copy(void) { BENCH_ADD(dv_cmp(a, b, RLC_DV_DIGS)); } BENCH_END; - BENCH_RUN("dv_cmp_const") { + BENCH_RUN("dv_cmp_sec") { rand_bytes((uint8_t *)a, RLC_DV_DIGS * sizeof(dig_t)); rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); - BENCH_ADD(dv_cmp_const(a, b, RLC_DV_DIGS)); + BENCH_ADD(dv_cmp_sec(a, b, RLC_DV_DIGS)); } BENCH_END; dv_free(a); diff --git a/bench/bench_eb.c b/bench/bench_eb.c index 1bd9d94d3..c6b4b945f 100644 --- a/bench/bench_eb.c +++ b/bench/bench_eb.c @@ -116,7 +116,7 @@ static void util(void) { BENCH_RUN("eb_rhs") { eb_rand(p); - BENCH_ADD(eb_rhs(q->x, p)); + BENCH_ADD(eb_rhs(q->x, p->x)); } BENCH_END; BENCH_RUN("eb_tab (4)") { diff --git a/bench/bench_ed.c b/bench/bench_ed.c index f2db37565..8f1f5f939 100644 --- a/bench/bench_ed.c +++ b/bench/bench_ed.c @@ -116,7 +116,7 @@ static void util(void) { BENCH_RUN("ed_rhs") { ed_rand(p); - BENCH_ADD(ed_rhs(q->x, p)); + BENCH_ADD(ed_rhs(q->x, p->x)); } BENCH_END; BENCH_RUN("ed_tab (4)") { diff --git a/bench/bench_ep.c b/bench/bench_ep.c index 54b36f890..26aee2cba 100644 --- a/bench/bench_ep.c +++ b/bench/bench_ep.c @@ -130,7 +130,7 @@ static void util(void) { BENCH_RUN("ep_rhs") { ep_rand(p); - BENCH_ADD(ep_rhs(q->x, p)); + BENCH_ADD(ep_rhs(q->x, p->x)); } BENCH_END; BENCH_RUN("ep_tab (4)") { diff --git a/bench/bench_epx.c b/bench/bench_epx.c index 3380f9801..27e96484c 100644 --- a/bench/bench_epx.c +++ b/bench/bench_epx.c @@ -240,8 +240,7 @@ static void arith2(void) { ep2_rand(p); ep2_add_projc(q, q, p); BENCH_ADD(ep2_add_projc(r, p, q)); - } - BENCH_END; + } BENCH_END; BENCH_RUN("ep2_add_projc (z2 = 1)") { ep2_rand(p); @@ -250,8 +249,7 @@ static void arith2(void) { ep2_rand(q); ep2_norm(q, q); BENCH_ADD(ep2_add_projc(r, p, q)); - } - BENCH_END; + } BENCH_END; BENCH_RUN("ep2_add_projc (z1,z2 = 1)") { ep2_rand(p); @@ -259,8 +257,36 @@ static void arith2(void) { ep2_rand(q); ep2_norm(q, q); BENCH_ADD(ep2_add_projc(r, p, q)); - } - BENCH_END; + } BENCH_END; +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + BENCH_RUN("ep2_add_jacob") { + ep2_rand(p); + ep2_rand(q); + ep2_add_jacob(p, p, q); + ep2_rand(q); + ep2_rand(p); + ep2_add_jacob(q, q, p); + BENCH_ADD(ep2_add_jacob(r, p, q)); + } BENCH_END; + + BENCH_RUN("ep2_add_jacob (z2 = 1)") { + ep2_rand(p); + ep2_rand(q); + ep2_add_jacob(p, p, q); + ep2_rand(q); + ep2_norm(q, q); + BENCH_ADD(ep2_add_jacob(r, p, q)); + } BENCH_END; + + BENCH_RUN("ep2_add_jacob (z1,z2 = 1)") { + ep2_rand(p); + ep2_norm(p, p); + ep2_rand(q); + ep2_norm(q, q); + BENCH_ADD(ep2_add_jacob(r, p, q)); + } BENCH_END; #endif BENCH_RUN("ep2_sub") { @@ -302,15 +328,28 @@ static void arith2(void) { ep2_rand(q); ep2_add_projc(p, p, q); BENCH_ADD(ep2_dbl_projc(r, p)); - } - BENCH_END; + } BENCH_END; BENCH_RUN("ep2_dbl_projc (z1 = 1)") { ep2_rand(p); ep2_norm(p, p); BENCH_ADD(ep2_dbl_projc(r, p)); - } - BENCH_END; + } BENCH_END; +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + BENCH_RUN("ep2_dbl_jacob") { + ep2_rand(p); + ep2_rand(q); + ep2_add_jacob(p, p, q); + BENCH_ADD(ep2_dbl_jacob(r, p)); + } BENCH_END; + + BENCH_RUN("ep2_dbl_jacob (z1 = 1)") { + ep2_rand(p); + ep2_norm(p, p); + BENCH_ADD(ep2_dbl_jacob(r, p)); + } BENCH_END; #endif BENCH_RUN("ep2_neg") { @@ -357,6 +396,14 @@ static void arith2(void) { } BENCH_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + BENCH_RUN("ep2_mul_lwreg") { + bn_rand_mod(k, n); + ep2_rand(p); + BENCH_ADD(ep2_mul_lwreg(q, p, k)); + } BENCH_END; +#endif + BENCH_RUN("ep2_mul_gen") { bn_rand_mod(k, n); BENCH_ADD(ep2_mul_gen(q, k)); @@ -902,6 +949,14 @@ static void arith3(void) { } BENCH_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + BENCH_RUN("ep3_mul_lwreg") { + bn_rand_mod(k, n); + ep3_rand(p); + BENCH_ADD(ep3_mul_lwreg(q, p, k)); + } BENCH_END; +#endif + BENCH_RUN("ep3_mul_gen") { bn_rand_mod(k, n); BENCH_ADD(ep3_mul_gen(q, k)); @@ -1396,6 +1451,14 @@ static void arith4(void) { } BENCH_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + BENCH_RUN("ep4_mul_lwreg") { + bn_rand_mod(k, n); + ep4_rand(p); + BENCH_ADD(ep4_mul_lwreg(q, p, k)); + } BENCH_END; +#endif + BENCH_RUN("ep4_mul_gen") { bn_rand_mod(k, n); BENCH_ADD(ep4_mul_gen(q, k)); @@ -1890,6 +1953,14 @@ static void arith8(void) { } BENCH_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + BENCH_RUN("ep8_mul_lwreg") { + bn_rand_mod(k, n); + ep8_rand(p); + BENCH_ADD(ep8_mul_lwreg(q, p, k)); + } BENCH_END; +#endif + BENCH_RUN("ep8_mul_gen") { bn_rand_mod(k, n); BENCH_ADD(ep8_mul_gen(q, k)); diff --git a/bench/bench_fp.c b/bench/bench_fp.c index ea3f576c2..0d8ae5254 100644 --- a/bench/bench_fp.c +++ b/bench/bench_fp.c @@ -69,6 +69,18 @@ static void util(void) { } BENCH_END; + BENCH_RUN("fp_copy_sec (0)") { + fp_rand(a); + BENCH_ADD(fp_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp_copy_sec (1)") { + fp_rand(a); + BENCH_ADD(fp_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp_zero") { fp_rand(a); BENCH_ADD(fp_zero(a)); diff --git a/bench/bench_fpx.c b/bench/bench_fpx.c index 818aa8b14..1a89a6333 100644 --- a/bench/bench_fpx.c +++ b/bench/bench_fpx.c @@ -66,6 +66,18 @@ static void util2(void) { } BENCH_END; + BENCH_RUN("fp2_copy_sec (0)") { + fp2_rand(a); + BENCH_ADD(fp2_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp2_copy_sec (1)") { + fp2_rand(a); + BENCH_ADD(fp2_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp2_neg") { fp2_rand(a); BENCH_ADD(fp2_neg(b, a)); @@ -453,6 +465,18 @@ static void util3(void) { } BENCH_END; + BENCH_RUN("fp3_copy_sec (0)") { + fp3_rand(a); + BENCH_ADD(fp3_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp3_copy_sec (1)") { + fp3_rand(a); + BENCH_ADD(fp3_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp3_neg") { fp3_rand(a); BENCH_ADD(fp3_neg(b, a)); @@ -753,6 +777,18 @@ static void util4(void) { } BENCH_END; + BENCH_RUN("fp4_copy_sec (0)") { + fp4_rand(a); + BENCH_ADD(fp4_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp4_copy_sec (1)") { + fp4_rand(a); + BENCH_ADD(fp4_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp4_neg") { fp4_rand(a); BENCH_ADD(fp4_neg(b, a)); @@ -979,6 +1015,18 @@ static void util6(void) { } BENCH_END; + BENCH_RUN("fp6_copy_sec (0)") { + fp6_rand(a); + BENCH_ADD(fp6_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp6_copy_sec (1)") { + fp6_rand(a); + BENCH_ADD(fp6_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp6_neg") { fp6_rand(a); BENCH_ADD(fp6_neg(b, a)); @@ -1191,6 +1239,18 @@ static void util8(void) { } BENCH_END; + BENCH_RUN("fp8_copy_sec (0)") { + fp8_rand(a); + BENCH_ADD(fp8_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp8_copy_sec (1)") { + fp8_rand(a); + BENCH_ADD(fp8_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp8_neg") { fp8_rand(a); BENCH_ADD(fp8_neg(b, a)); @@ -1241,13 +1301,13 @@ static void util8(void) { BENCH_RUN("fp8_write_bin") { fp8_rand(a); - BENCH_ADD(fp8_write_bin(bin, sizeof(bin), a)); + BENCH_ADD(fp8_write_bin(bin, sizeof(bin), a, 0)); } BENCH_END; BENCH_RUN("fp8_read_bin") { fp8_rand(a); - fp8_write_bin(bin, sizeof(bin), a); + fp8_write_bin(bin, sizeof(bin), a, 0); BENCH_ADD(fp8_read_bin(a, bin, sizeof(bin))); } BENCH_END; @@ -1483,6 +1543,18 @@ static void util9(void) { } BENCH_END; + BENCH_RUN("fp9_copy_sec (0)") { + fp9_rand(a); + BENCH_ADD(fp9_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp9_copy_sec (1)") { + fp9_rand(a); + BENCH_ADD(fp9_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp9_neg") { fp9_rand(a); BENCH_ADD(fp9_neg(b, a)); @@ -1695,6 +1767,18 @@ static void util12(void) { } BENCH_END; + BENCH_RUN("fp12_copy_sec (0)") { + fp12_rand(a); + BENCH_ADD(fp12_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp12_copy_sec (1)") { + fp12_rand(a); + BENCH_ADD(fp12_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp12_neg") { fp12_rand(a); BENCH_ADD(fp12_neg(b, a)); @@ -1976,16 +2060,6 @@ static void arith12(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 12) { - BENCH_RUN("fp12_exp_cyc (gls)") { - fp12_rand(a); - fp12_conv_cyc(a, a); - bn_rand(e, RLC_POS, RLC_FP_BITS); - BENCH_ADD(fp12_exp_cyc_gls(c, a, e)); - } - BENCH_END; - } - BENCH_RUN("fp12_exp_cyc (param or sparse)") { fp12_rand(a); fp12_conv_cyc(a, a); @@ -2093,6 +2167,18 @@ static void util16(void) { } BENCH_END; + BENCH_RUN("fp16_copy_sec (0)") { + fp16_rand(a); + BENCH_ADD(fp16_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp16_copy_sec (1)") { + fp16_rand(a); + BENCH_ADD(fp16_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp16_neg") { fp16_rand(a); BENCH_ADD(fp16_neg(b, a)); @@ -2251,16 +2337,6 @@ static void arith16(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 16) { - BENCH_RUN("fp16_exp_cyc (gls)") { - fp16_rand(a); - fp16_conv_cyc(a, a); - bn_rand(e, RLC_POS, RLC_FP_BITS); - BENCH_ADD(fp16_exp_cyc_gls(c, a, e)); - } - BENCH_END; - } - BENCH_RUN("fp16_exp_cyc (param or sparse)") { fp16_rand(a); fp16_conv_cyc(a, a); @@ -2328,6 +2404,18 @@ static void util18(void) { } BENCH_END; + BENCH_RUN("fp18_copy_sec (0)") { + fp18_rand(a); + BENCH_ADD(fp18_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp18_copy_sec (1)") { + fp18_rand(a); + BENCH_ADD(fp18_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp18_neg") { fp18_rand(a); BENCH_ADD(fp18_neg(b, a)); @@ -2609,16 +2697,6 @@ static void arith18(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 18) { - BENCH_RUN("fp18_exp_cyc (gls)") { - fp18_rand(a); - fp18_conv_cyc(a, a); - bn_rand(e, RLC_POS, RLC_FP_BITS); - BENCH_ADD(fp18_exp_cyc_gls(c, a, e)); - } - BENCH_END; - } - BENCH_RUN("fp18_exp_cyc (param or sparse)") { fp18_rand(a); fp18_conv_cyc(a, a); @@ -2712,6 +2790,18 @@ static void util24(void) { } BENCH_END; + BENCH_RUN("fp24_copy_sec (0)") { + fp24_rand(a); + BENCH_ADD(fp24_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp24_copy_sec (1)") { + fp24_rand(a); + BENCH_ADD(fp24_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp24_neg") { fp24_rand(a); BENCH_ADD(fp24_neg(b, a)); @@ -2930,16 +3020,6 @@ static void arith24(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 24) { - BENCH_RUN("fp24_exp_cyc (gls)") { - fp24_rand(a); - fp24_conv_cyc(a, a); - bn_rand(e, RLC_POS, RLC_FP_BITS); - BENCH_ADD(fp24_exp_cyc_gls(c, a, e)); - } - BENCH_END; - } - BENCH_RUN("fp24_exp_cyc (param or sparse)") { fp24_rand(a); fp24_conv_cyc(a, a); @@ -3033,6 +3113,18 @@ static void util48(void) { } BENCH_END; + BENCH_RUN("fp48_copy_sec (0)") { + fp48_rand(a); + BENCH_ADD(fp48_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp48_copy_sec (1)") { + fp48_rand(a); + BENCH_ADD(fp48_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp48_neg") { fp48_rand(a); BENCH_ADD(fp48_neg(b, a)); @@ -3296,16 +3388,6 @@ static void arith48(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 48) { - BENCH_RUN("fp48_exp_cyc (gls)") { - fp48_rand(a); - fp48_conv_cyc(a, a); - bn_rand(e, RLC_POS, RLC_FP_BITS); - BENCH_ADD(fp48_exp_cyc_gls(c, a, e)); - } - BENCH_END; - } - BENCH_RUN("fp48_exp_cyc (param or sparse)") { fp48_rand(a); fp48_conv_cyc(a, a); @@ -3399,6 +3481,18 @@ static void util54(void) { } BENCH_END; + BENCH_RUN("fp54_copy_sec (0)") { + fp54_rand(a); + BENCH_ADD(fp54_copy_sec(b, a, 0)); + } + BENCH_END; + + BENCH_RUN("fp54_copy_sec (1)") { + fp54_rand(a); + BENCH_ADD(fp54_copy_sec(b, a, 1)); + } + BENCH_END; + BENCH_RUN("fp54_neg") { fp54_rand(a); BENCH_ADD(fp54_neg(b, a)); @@ -3778,7 +3872,7 @@ int main(void) { arith6(); } - if (fp_prime_get_qnr() && (ep_param_embed() >= 8)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 8)) { util_banner("Octic extension:", 0); util_banner("Utilities:", 1); memory8(); @@ -3787,7 +3881,7 @@ int main(void) { arith8(); } - if (fp_prime_get_cnr() && (ep_param_embed() >= 9)) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 9)) { util_banner("Nonic extension:", 0); util_banner("Utilities:", 1); memory9(); @@ -3796,7 +3890,7 @@ int main(void) { arith9(); } - if (fp_prime_get_qnr() && fp_prime_get_cnr() && (ep_param_embed() >= 12)) { + if (fp_prime_get_qnr() && fp_prime_get_cnr() && (ep_curve_embed() >= 12)) { util_banner("Dodecic extension:", 0); util_banner("Utilities:", 1); memory12(); @@ -3805,7 +3899,7 @@ int main(void) { arith12(); } - if (fp_prime_get_qnr() && (ep_param_embed() >= 16)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 16)) { util_banner("Sextadecic extension:", 0); util_banner("Utilities:", 1); memory16(); @@ -3815,7 +3909,7 @@ int main(void) { arith16(); } - if (fp_prime_get_cnr() && (ep_param_embed() >= 18)) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 18)) { util_banner("Octdecic extension:", 0); util_banner("Utilities:", 1); memory18(); @@ -3825,7 +3919,7 @@ int main(void) { arith18(); } - if (fp_prime_get_qnr() && (ep_param_embed() >= 24)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 24)) { util_banner("Extension of degree 24:", 0); util_banner("Utilities:", 1); memory24(); @@ -3834,7 +3928,7 @@ int main(void) { arith24(); } - if (fp_prime_get_qnr() && (ep_param_embed() >= 48)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 48)) { util_banner("Extension of degree 48:", 0); util_banner("Utilities:", 1); memory48(); @@ -3843,7 +3937,7 @@ int main(void) { arith48(); } - if (fp_prime_get_cnr() && (ep_param_embed() >= 54)) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 54)) { util_banner("Extension of degree 54:", 0); util_banner("Utilities:", 1); memory54(); diff --git a/bench/bench_pc.c b/bench/bench_pc.c index 693173c7f..064f05f1c 100755 --- a/bench/bench_pc.c +++ b/bench/bench_pc.c @@ -216,6 +216,14 @@ static void arith1(void) { } BENCH_END; + BENCH_RUN("g1_mul_sec") { + bn_rand(k, RLC_POS, bn_bits(n)); + bn_rand_mod(k, n); + g1_rand(p); + BENCH_ADD(g1_mul_sec(q, p, k)); + } + BENCH_END; + BENCH_RUN("g1_mul_gen") { bn_rand(k, RLC_POS, bn_bits(n)); bn_rand_mod(k, n); @@ -468,6 +476,14 @@ static void arith2(void) { } BENCH_END; + BENCH_RUN("g2_mul_sec") { + bn_rand(k, RLC_POS, bn_bits(n)); + bn_rand_mod(k, n); + g2_rand(p); + BENCH_ADD(g2_mul_sec(q, p, k)); + } + BENCH_END; + BENCH_RUN("g2_mul_gen") { bn_rand(k, RLC_POS, bn_bits(n)); bn_rand_mod(k, n); @@ -621,7 +637,7 @@ static void util(void) { BENCH_ADD(gt_read_bin(a, bin, l)); } BENCH_END; - if (ep_param_embed() == 12) { + if (ep_curve_embed() == 12) { BENCH_RUN("gt_write_bin (1)") { gt_rand(a); l = gt_size_bin(a, 1); @@ -684,6 +700,14 @@ static void arith(void) { } BENCH_END; + BENCH_RUN("gt_exp_sec") { + gt_rand(a); + pc_get_ord(d); + bn_rand_mod(e, d); + BENCH_ADD(gt_exp_sec(c, a, e)); + } + BENCH_END; + BENCH_RUN("gt_exp_gen") { pc_get_ord(d); bn_rand_mod(e, d); diff --git a/bench/bench_pp.c b/bench/bench_pp.c index a90c4e329..12407a134 100644 --- a/bench/bench_pp.c +++ b/bench/bench_pp.c @@ -1345,35 +1345,35 @@ int main(void) { ep_param_print(); util_banner("Arithmetic:", 1); - if (ep_param_embed() == 2) { + if (ep_curve_embed() == 2) { pairing2(); } - if (ep_param_embed() == 8) { + if (ep_curve_embed() == 8) { pairing8(); } - if (ep_param_embed() == 12) { + if (ep_curve_embed() == 12) { pairing12(); } - if (ep_param_embed() == 16) { + if (ep_curve_embed() == 16) { pairing16(); } - if (ep_param_embed() == 18) { + if (ep_curve_embed() == 18) { pairing18(); } - if (ep_param_embed() == 48) { + if (ep_curve_embed() == 48) { pairing24(); } - if (ep_param_embed() == 48) { + if (ep_curve_embed() == 48) { pairing48(); } - if (ep_param_embed() == 54) { + if (ep_curve_embed() == 54) { pairing54(); } diff --git a/cmake/gmp.cmake b/cmake/gmp.cmake index abb00c44c..f71f64e65 100644 --- a/cmake/gmp.cmake +++ b/cmake/gmp.cmake @@ -36,7 +36,18 @@ if (GMP_INCLUDE_DIR AND GMP_LIBRARIES) unset(GMP_LIBRARIES CACHE) endif (GMP_INCLUDE_DIR AND GMP_LIBRARIES) -find_path(GMP_INCLUDE_DIR NAMES gmp.h) +find_path(GMP_INCLUDE_DIR gmp.h + PATHS + ENV GMP_ROOT + ENV GMP_INCLUDE_DIR + ${GMP_ROOT} + /usr + /usr/local + $ENV{HOME}/.local + PATH_SUFFIXES + include +) + if(STBIN) find_library(GMP_LIBRARIES NAMES libgmp.a gmp.lib libgmp-10 libgmp gmp) else(STBIN) diff --git a/demo/ers-etrs/test-bench b/demo/ers-etrs/test-bench new file mode 100755 index 000000000..f412aa9ed Binary files /dev/null and b/demo/ers-etrs/test-bench differ diff --git a/include/relic_core.h b/include/relic_core.h index 02e08741c..13805aeb5 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_dv.h b/include/relic_dv.h index cb7244cf7..6909c89a2 100644 --- a/include/relic_dv.h +++ b/include/relic_dv.h @@ -166,9 +166,9 @@ void dv_copy(dig_t *c, const dig_t *a, size_t digits); * @param[out] c - the destination. * @paraim[in] a - the source. * @param[in] digits - the number of digits to copy. - * @param[in] cond - the condition to evaluate. + * @param[in] bit - the condition bit to evaluate. */ -void dv_copy_cond(dig_t *c, const dig_t *a, size_t digits, dig_t cond); +void dv_copy_sec(dig_t *c, const dig_t *a, size_t digits, dig_t bit); /** * Conditionally swap two digit vectors. @@ -176,9 +176,9 @@ void dv_copy_cond(dig_t *c, const dig_t *a, size_t digits, dig_t cond); * @param[in,out] c - the destination. * @paraim[in,out] a - the source. * @param[in] digits - the number of digits to copy. - * @param[in] cond - the condition to evaluate. + * @param[in] bit - the condition bit to evaluate. */ -void dv_swap_cond(dig_t *c, dig_t *a, size_t digits, dig_t cond); +void dv_swap_sec(dig_t *c, dig_t *a, size_t digits, dig_t bit); /** * Returns the result of a comparison between two digit vectors. @@ -198,7 +198,7 @@ int dv_cmp(const dig_t *a, const dig_t *b, size_t size); * @param[in] size - the length in digits of the vectors. * @return RLC_EQ if they are equal and RLC_NE otherwise. */ -int dv_cmp_const(const dig_t *a, const dig_t *b, size_t size); +int dv_cmp_sec(const dig_t *a, const dig_t *b, size_t size); /** * Allocates and initializes a temporary double-precision digit vector. diff --git a/include/relic_eb.h b/include/relic_eb.h index 8fbd928b0..1a5da9899 100644 --- a/include/relic_eb.h +++ b/include/relic_eb.h @@ -511,13 +511,13 @@ void eb_rand(eb_t p); void eb_blind(eb_t r, const eb_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain binary elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void eb_rhs(fb_t rhs, const eb_t p); +void eb_rhs(fb_t rhs, const fb_t p); /** Tests if a point is in the curve. * diff --git a/include/relic_ed.h b/include/relic_ed.h index abc888f3f..b30d196fe 100644 --- a/include/relic_ed.h +++ b/include/relic_ed.h @@ -321,13 +321,13 @@ void ed_rand(ed_t p); void ed_blind(ed_t r, const ed_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * Edwards elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain Edwards elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ed_rhs(fp_t rhs, const ed_t p); +void ed_rhs(fp_t rhs, const fp_t p); /** * Copies the second argument to the first argument. diff --git a/include/relic_ep.h b/include/relic_ep.h index 628180a41..9d321e6e2 100644 --- a/include/relic_ep.h +++ b/include/relic_ep.h @@ -185,6 +185,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. */ @@ -221,7 +223,7 @@ enum { #define RLC_EP_TABLE_COMBD (1 << (RLC_DEPTH + 1)) /** - * Size of a precomputation table using the w-(T)NAF method. + * Size of a precomputation table using the w-NAF method. */ #define RLC_EP_TABLE_LWNAF (1 << (RLC_DEPTH - 2)) @@ -467,6 +469,16 @@ typedef iso_st *iso_t; #define ep_mul_sim(R, P, K, Q, M) ep_mul_sim_joint(R, P, K, Q, M) #endif +/** + * Multiplies a point in an elliptic curve over by an unrestricted scalar. + * Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep_mul_big(R, P, K) ep_mul_basic(R, P, K) + /** * Hashes a byte string to a prime elliptic point or the right order. * Computes R = H(s). @@ -547,13 +559,6 @@ int ep_curve_opt_a(void); */ int ep_curve_opt_b(void); -/** - * Returns a optimization identifier based on the b-coefficient of the curve. - * - * @return the optimization identifier. - */ -int ep_curve_opt_b3(void); - /** * Multiplies a field element by the a-coefficient of the curve. * @@ -570,13 +575,6 @@ void ep_curve_mul_a(fp_t c, const fp_t a); */ void ep_curve_mul_b(fp_t c, const fp_t a); -/** - * Multiplies a field element by the b3 value of the curve. - * - * @param[out] c - the result. - * @param[in] a - the field element to multiply. - */ -void ep_curve_mul_b3(fp_t c, const fp_t a); /** * Tests if the configured prime elliptic curve is a Koblitz curve. * @@ -683,6 +681,17 @@ void ep_curve_set_super(const fp_t a, const fp_t b, const ep_t g, const bn_t r, void ep_curve_set_endom(const fp_t a, const fp_t b, const ep_t g, const bn_t r, const bn_t h, const fp_t beta, const bn_t l, int ctmap); +/** + * Returns the embedding degree of the currently configured elliptic curve. + */ +int ep_curve_embed(void); + +/** + * Returns the dimension of Frobenius expansions of the currently configured + * elliptic curve. + */ +int ep_curve_frdim(void); + /** * Configures a prime elliptic curve by its parameter identifier. * @@ -745,11 +754,6 @@ void ep_param_print(void); */ int ep_param_level(void); -/** - * Returns the embedding degree of the currently configured elliptic curve. - */ -int ep_param_embed(void); - /** * Tests if a point on a prime elliptic curve is at the infinity. * @@ -798,13 +802,13 @@ void ep_rand(ep_t p); void ep_blind(ep_t r, const ep_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * prime elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain prime elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ep_rhs(fp_t rhs, const ep_t p); +void ep_rhs(fp_t rhs, const fp_t x); /** * Tests if a point is in the curve. diff --git a/include/relic_epx.h b/include/relic_epx.h index 9cb652243..ffd06f2ee 100644 --- a/include/relic_epx.h +++ b/include/relic_epx.h @@ -33,7 +33,7 @@ * The scalar multiplication functions are only guaranteed to work * in the prime order subgroup used by pairings. If you need a generic scalar - * multiplication function, use \sa ep2_mul_big(). + * multiplication function, use epx_mul_big(). * * @ingroup epx */ @@ -150,7 +150,7 @@ typedef ep3_st *ep3_t; #endif /** - * Represents an elliptic curve point over a octic extension over a prime + * Represents an elliptic curve point over an octic extension over a prime * field. */ typedef struct { @@ -165,7 +165,7 @@ typedef struct { } ep4_st; /** - * Pointer to an elliptic curve point over a octic extension field. + * Pointer to an elliptic curve point over an octic extension field. */ #if ALLOC == AUTO typedef ep4_st ep4_t[1]; @@ -441,9 +441,11 @@ typedef iso2_st *iso2_t; * @param[in] Q - the second point to add. */ #if EP_ADD == BASIC -#define ep2_add(R, P, Q) ep2_add_basic(R, P, Q); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep2_add(R, P, Q) ep2_add_projc(R, P, Q); +#define ep2_add(R, P, Q) ep2_add_basic(R, P, Q) +#elif EP_ADD == PROJC +#define ep2_add(R, P, Q) ep2_add_projc(R, P, Q) +#elif EP_ADD == JACOB +#define ep2_add(R, P, Q) ep2_add_jacob(R, P, Q) #endif /** @@ -454,9 +456,11 @@ typedef iso2_st *iso2_t; * @param[in] P - the point to double. */ #if EP_ADD == BASIC -#define ep2_dbl(R, P) ep2_dbl_basic(R, P); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep2_dbl(R, P) ep2_dbl_projc(R, P); +#define ep2_dbl(R, P) ep2_dbl_basic(R, P) +#elif EP_ADD == PROJC +#define ep2_dbl(R, P) ep2_dbl_projc(R, P) +#elif EP_ADD == JACOB +#define ep2_dbl(R, P) ep2_dbl_jacob(R, P) #endif /** @@ -473,8 +477,10 @@ typedef iso2_st *iso2_t; #define ep2_mul(R, P, K) ep2_mul_slide(R, P, K) #elif EP_MUL == MONTY #define ep2_mul(R, P, K) ep2_mul_monty(R, P, K) -#elif EP_MUL == LWNAF || EP_MUL == LWREG +#elif EP_MUL == LWNAF #define ep2_mul(R, P, K) ep2_mul_lwnaf(R, P, K) +#elif EP_MUL == LWREG +#define ep2_mul(R, P, K) ep2_mul_lwreg(R, P, K) #endif /** @@ -534,6 +540,16 @@ typedef iso2_st *iso2_t; #define ep2_mul_sim(R, P, K, Q, M) ep2_mul_sim_joint(R, P, K, Q, M) #endif +/** + * Multiplies a point in an elliptic curve over a quadratic extension field by + * an unrestricted integer scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep2_mul_big(R, P, K) ep2_mul_basic(R, P, K) + /** * Hashes a byte string to a prime elliptic point or the right order. * Computes R = H(s). @@ -559,9 +575,11 @@ typedef iso2_st *iso2_t; * @param[in] Q - the second point to add. */ #if EP_ADD == BASIC -#define ep3_add(R, P, Q) ep3_add_basic(R, P, Q); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep3_add(R, P, Q) ep3_add_projc(R, P, Q); +#define ep3_add(R, P, Q) ep3_add_basic(R, P, Q) +#elif EP_ADD == PROJC +#define ep3_add(R, P, Q) ep3_add_projc(R, P, Q) +#elif EP_ADD == JACOB +#define ep3_add(R, P, Q) ep3_add_jacob(R, P, Q) #endif /** @@ -572,9 +590,11 @@ typedef iso2_st *iso2_t; * @param[in] P - the point to double. */ #if EP_ADD == BASIC -#define ep3_dbl(R, P) ep3_dbl_basic(R, P); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep3_dbl(R, P) ep3_dbl_projc(R, P); +#define ep3_dbl(R, P) ep3_dbl_basic(R, P) +#elif EP_ADD == PROJC +#define ep3_dbl(R, P) ep3_dbl_projc(R, P) +#elif EP_ADD == JACOB +#define ep3_dbl(R, P) ep3_dbl_jacob(R, P) #endif /** @@ -591,8 +611,10 @@ typedef iso2_st *iso2_t; #define ep3_mul(R, P, K) ep3_mul_slide(R, P, K) #elif EP_MUL == MONTY #define ep3_mul(R, P, K) ep3_mul_monty(R, P, K) -#elif EP_MUL == LWNAF || EP_MUL == LWREG +#elif EP_MUL == LWNAF #define ep3_mul(R, P, K) ep3_mul_lwnaf(R, P, K) +#elif EP_MUL == LWREG +#define ep3_mul(R, P, K) ep3_mul_lwreg(R, P, K) #endif /** @@ -653,7 +675,17 @@ typedef iso2_st *iso2_t; #endif /** - * Adds two points in an elliptic curve over a octic extension field. + * Multiplies a point in an elliptic curve over a cubic extension field by + * an unrestricted integer scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep3_mul_big(R, P, K) ep3_mul_basic(R, P, K) + +/** + * Adds two points in an elliptic curve over a quartic extension field. * Computes R = P + Q. * * @param[out] R - the result. @@ -661,36 +693,30 @@ typedef iso2_st *iso2_t; * @param[in] Q - the second point to add. */ #if EP_ADD == BASIC -#define ep4_add(R, P, Q) ep4_add_basic(R, P, Q); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep4_add(R, P, Q) ep4_add_projc(R, P, Q); +#define ep4_add(R, P, Q) ep4_add_basic(R, P, Q) +#elif EP_ADD == PROJC +#define ep4_add(R, P, Q) ep4_add_projc(R, P, Q) +#elif EP_ADD == JACOB +#define ep4_add(R, P, Q) ep4_add_jacob(R, P, Q) #endif /** - * Doubles a point in an elliptic curve over a octic extension field. + * Doubles a point in an elliptic curve over a quartic extension field. * Computes R = 2P. * * @param[out] R - the result. * @param[in] P - the point to double. */ #if EP_ADD == BASIC -#define ep4_dbl(R, P) ep4_dbl_basic(R, P); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep4_dbl(R, P) ep4_dbl_projc(R, P); +#define ep4_dbl(R, P) ep4_dbl_basic(R, P) +#elif EP_ADD == PROJC +#define ep4_dbl(R, P) ep4_dbl_projc(R, P) +#elif EP_ADD == JACOB +#define ep4_dbl(R, P) ep4_dbl_jacob(R, P) #endif /** - * Multiplies a point in an elliptic curve over a octic extension field by - * an unrestricted integer scalar. Computes R = [k]P. - * - * @param[out] R - the result. - * @param[in] P - the point to multiply. - * @param[in] K - the integer. - */ -#define ep4_mul_big(R, P, K) ep4_mul_basic(R, P, K) - -/** - * Multiplies a point in an elliptic curve over a octic extension field. + * Multiplies a point in an elliptic curve over a quartic extension field. * Computes R = [k]P. * * @param[out] R - the result. @@ -703,13 +729,15 @@ typedef iso2_st *iso2_t; #define ep4_mul(R, P, K) ep4_mul_slide(R, P, K) #elif EP_MUL == MONTY #define ep4_mul(R, P, K) ep4_mul_monty(R, P, K) -#elif EP_MUL == LWNAF || EP_MUL == LWREG +#elif EP_MUL == LWNAF #define ep4_mul(R, P, K) ep4_mul_lwnaf(R, P, K) +#elif EP_MUL == LWREG +#define ep4_mul(R, P, K) ep4_mul_lwreg(R, P, K) #endif /** * Builds a precomputation table for multiplying a fixed prime elliptic point - * over a octic extension. + * over a quartic extension. * * @param[out] T - the precomputation table. * @param[in] P - the point to multiply. @@ -726,7 +754,7 @@ typedef iso2_st *iso2_t; #endif /** - * Multiplies a fixed prime elliptic point over a octic extension using a + * Multiplies a fixed prime elliptic point over a quartic extension using a * precomputation table. Computes R = [k]P. * * @param[out] R - the result. @@ -765,7 +793,17 @@ typedef iso2_st *iso2_t; #endif /** - * Adds two points in an elliptic curve over a octic extension field. + * Multiplies a point in an elliptic curve over a quartic extension field by + * an unrestricted integer scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep4_mul_big(R, P, K) ep4_mul_basic(R, P, K) + +/** + * Adds two points in an elliptic curve over an octic extension field. * Computes R = P + Q. * * @param[out] R - the result. @@ -773,36 +811,30 @@ typedef iso2_st *iso2_t; * @param[in] Q - the second point to add. */ #if EP_ADD == BASIC -#define ep8_add(R, P, Q) ep8_add_basic(R, P, Q); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep8_add(R, P, Q) ep8_add_projc(R, P, Q); +#define ep8_add(R, P, Q) ep8_add_basic(R, P, Q) +#elif EP_ADD == PROJC +#define ep8_add(R, P, Q) ep8_add_projc(R, P, Q) +#elif EP_ADD == JACOB +#define ep8_add(R, P, Q) ep8_add_jacob(R, P, Q) #endif /** - * Doubles a point in an elliptic curve over a octic extension field. + * Doubles a point in an elliptic curve over an octic extension field. * Computes R = 2P. * * @param[out] R - the result. * @param[in] P - the point to double. */ #if EP_ADD == BASIC -#define ep8_dbl(R, P) ep8_dbl_basic(R, P); -#elif EP_ADD == PROJC || EP_ADD == JACOB -#define ep8_dbl(R, P) ep8_dbl_projc(R, P); +#define ep8_dbl(R, P) ep8_dbl_basic(R, P) +#elif EP_ADD == PROJC +#define ep8_dbl(R, P) ep8_dbl_projc(R, P) +#elif EP_ADD == JACOB +#define ep8_dbl(R, P) ep8_dbl_jacob(R, P) #endif /** - * Multiplies a point in an elliptic curve over a octic extension field by - * an unrestricted integer scalar. Computes R = [k]P. - * - * @param[out] R - the result. - * @param[in] P - the point to multiply. - * @param[in] K - the integer. - */ -#define ep8_mul_big(R, P, K) ep8_mul_basic(R, P, K) - -/** - * Multiplies a point in an elliptic curve over a octic extension field. + * Multiplies a point in an elliptic curve over an octic extension field. * Computes R = [k]P. * * @param[out] R - the result. @@ -815,13 +847,15 @@ typedef iso2_st *iso2_t; #define ep8_mul(R, P, K) ep8_mul_slide(R, P, K) #elif EP_MUL == MONTY #define ep8_mul(R, P, K) ep8_mul_monty(R, P, K) -#elif EP_MUL == LWNAF || EP_MUL == LWREG +#elif EP_MUL == LWNAF #define ep8_mul(R, P, K) ep8_mul_lwnaf(R, P, K) +#elif EP_MUL == LWREG +#define ep8_mul(R, P, K) ep8_mul_lwreg(R, P, K) #endif /** * Builds a precomputation table for multiplying a fixed prime elliptic point - * over a octic extension. + * over an octic extension. * * @param[out] T - the precomputation table. * @param[in] P - the point to multiply. @@ -838,7 +872,7 @@ typedef iso2_st *iso2_t; #endif /** - * Multiplies a fixed prime elliptic point over a octic extension using a + * Multiplies a fixed prime elliptic point over an octic extension using a * precomputation table. Computes R = [k]P. * * @param[out] R - the result. @@ -876,6 +910,16 @@ typedef iso2_st *iso2_t; #define ep8_mul_sim(R, P, K, Q, M) ep8_mul_sim_joint(R, P, K, Q, M) #endif +/** + * Multiplies a point in an elliptic curve over an octic extension field by + * an unrestricted integer scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the point to multiply. + * @param[in] K - the integer. + */ +#define ep8_mul_big(R, P, K) ep8_mul_basic(R, P, K) + /*============================================================================*/ /* Function prototypes */ /*============================================================================*/ @@ -918,6 +962,22 @@ int ep2_curve_opt_a(void); */ int ep2_curve_opt_b(void); +/** + * Multiplies a field element by the a-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep2_curve_mul_a(fp2_t c, const fp2_t a); + +/** + * Multiplies a field element by the b-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep2_curve_mul_b(fp2_t c, const fp2_t a); + /** * Tests if the configured elliptic curve is a twist. * @@ -1032,13 +1092,13 @@ void ep2_rand(ep2_t p); void ep2_blind(ep2_t r, const ep2_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain prime elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ep2_rhs(fp2_t rhs, const ep2_t p); +void ep2_rhs(fp2_t rhs, const fp2_t x); /** * Tests if a point is in the curve. @@ -1137,6 +1197,16 @@ void ep2_add_slp_basic(ep2_t r, fp2_t s, const ep2_t p, const ep2_t q); */ void ep2_add_projc(ep2_t r, const ep2_t p, const ep2_t q); +/** + * Adds two points represented in Jacobian coordinates in an elliptic curve + * over a quadratic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep2_add_jacob(ep2_t r, const ep2_t p, const ep2_t q); + /** * Subtracts a point in an elliptic curve over a quadratic extension from * another. @@ -1148,7 +1218,7 @@ void ep2_add_projc(ep2_t r, const ep2_t p, const ep2_t q); void ep2_sub(ep2_t r, const ep2_t p, const ep2_t q); /** - * Doubles a points represented in affine coordinates in an elliptic curve over + * Doubles a point represented in affine coordinates in an elliptic curve over * a quadratic extension. * * @param[out] r - the result. @@ -1157,7 +1227,7 @@ void ep2_sub(ep2_t r, const ep2_t p, const ep2_t q); void ep2_dbl_basic(ep2_t r, const ep2_t p); /** - * Doubles a points represented in affine coordinates in an elliptic curve over + * Doubles a point represented in affine coordinates in an elliptic curve over * a quadratic extension and returns the computed slope. * * @param[out] r - the result. @@ -1167,7 +1237,7 @@ void ep2_dbl_basic(ep2_t r, const ep2_t p); void ep2_dbl_slp_basic(ep2_t r, fp2_t s, const ep2_t p); /** - * Doubles a points represented in projective coordinates in an elliptic curve + * Doubles a point represented in projective coordinates in an elliptic curve * over a quadratic extension. * * @param[out] r - the result. @@ -1175,6 +1245,15 @@ void ep2_dbl_slp_basic(ep2_t r, fp2_t s, const ep2_t p); */ void ep2_dbl_projc(ep2_t r, const ep2_t p); +/** + * Doubles a point represented in Jacobian coordinates in an elliptic curve + * over a quadratic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +void ep2_dbl_jacob(ep2_t r, const ep2_t p); + /** * Multiplies a prime elliptic point by an integer using the binary method. * @@ -1525,12 +1604,12 @@ void ep2_pck(ep2_t r, const ep2_t p); int ep2_upk(ep2_t r, const ep2_t p); /** - * Initializes the elliptic curve over octic extension. + * Initializes the elliptic curve over cubic extension. */ void ep3_curve_init(void); /** - * Finalizes the elliptic curve over octic extension. + * Finalizes the elliptic curve over cubic extension. */ void ep3_curve_clean(void); @@ -1539,14 +1618,14 @@ void ep3_curve_clean(void); * * @return the 'a' coefficient of the elliptic curve. */ -void ep3_curve_get_a(fp3_t a); +fp_t *ep3_curve_get_a(void); /** * Returns the 'b' coefficient of the currently configured elliptic curve. * * @param[out] b - the 'b' coefficient of the elliptic curve. */ -void ep3_curve_get_b(fp3_t b); +fp_t *ep3_curve_get_b(void); /** * Returns a optimization identifier based on the 'a' coefficient of the curve. @@ -1562,6 +1641,22 @@ int ep3_curve_opt_a(void); */ int ep3_curve_opt_b(void); +/** + * Multiplies a field element by the a-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep3_curve_mul_a(fp3_t c, const fp3_t a); + +/** + * Multiplies a field element by the b-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep3_curve_mul_b(fp3_t c, const fp3_t a); + /** * Tests if the configured elliptic curve is a twist. * @@ -1598,7 +1693,7 @@ void ep3_curve_get_ord(bn_t n); void ep3_curve_get_cof(bn_t h); /** - * Configures an elliptic curve over a octic extension by its coefficients. + * Configures an elliptic curve over a cubic extension by its coefficients. * * @param[in] a - the 'a' coefficient of the curve. * @param[in] b - the 'b' coefficient of the curve. @@ -1664,13 +1759,13 @@ void ep3_rand(ep3_t p); void ep3_blind(ep3_t r, const ep3_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain prime elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ep3_rhs(fp3_t rhs, const ep3_t p); +void ep3_rhs(fp3_t rhs, const fp3_t x); /** * Tests if a point is in the curve. @@ -1697,7 +1792,7 @@ void ep3_print(const ep3_t p); /** * Returns the number of bytes necessary to store a prime elliptic curve point - * over a octic extension with optional point compression. + * over a cubic extension with optional point compression. * * @param[in] a - the prime field element. * @param[in] pack - the flag to indicate compression. @@ -1706,7 +1801,7 @@ void ep3_print(const ep3_t p); int ep3_size_bin(const ep3_t a, int pack); /** - * Reads a prime elliptic curve point over a octic extension from a byte + * Reads a prime elliptic curve point over a cubic extension from a byte * vector in big-endian format. * * @param[out] a - the result. @@ -1718,7 +1813,7 @@ int ep3_size_bin(const ep3_t a, int pack); void ep3_read_bin(ep3_t a, const uint8_t *bin, size_t len); /** - * Writes a prime elliptic curve pointer over a octic extension to a byte + * Writes a prime elliptic curve pointer over a cubic extension to a byte * vector in big-endian format with optional point compression. * * @param[out] bin - the byte vector. @@ -1731,7 +1826,7 @@ void ep3_write_bin(uint8_t *bin, size_t len, const ep3_t a, int pack); /** * Negates a point represented in affine coordinates in an elliptic curve over - * a octic extension. + * a cubic extension. * * @param[out] r - the result. * @param[out] p - the point to negate. @@ -1740,7 +1835,7 @@ void ep3_neg(ep3_t r, const ep3_t p); /** * Adds to points represented in affine coordinates in an elliptic curve over a - * octic extension. + * cubic extension. * * @param[out] r - the result. * @param[in] p - the first point to add. @@ -1750,7 +1845,7 @@ void ep3_add_basic(ep3_t r, const ep3_t p, const ep3_t q); /** * Adds to points represented in affine coordinates in an elliptic curve over a - * octic extension and returns the computed slope. + * cubic extension and returns the computed slope. * * @param[out] r - the result. * @param[out] s - the slope. @@ -1761,7 +1856,7 @@ void ep3_add_slp_basic(ep3_t r, fp3_t s, const ep3_t p, const ep3_t q); /** * Adds two points represented in projective coordinates in an elliptic curve - * over a octic extension. + * over a cubic extension. * * @param[out] r - the result. * @param[in] p - the first point to add. @@ -1769,8 +1864,18 @@ void ep3_add_slp_basic(ep3_t r, fp3_t s, const ep3_t p, const ep3_t q); */ void ep3_add_projc(ep3_t r, const ep3_t p, const ep3_t q); +/** + * Adds two points represented in Jacobian coordinates in an elliptic curve + * over a cubic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep3_add_jacob(ep3_t r, const ep3_t p, const ep3_t q); + /** - * Subtracts a point in an elliptic curve over a octic extension from + * Subtracts a point in an elliptic curve over a cubic extension from * another. * * @param[out] r - the result. @@ -1780,8 +1885,8 @@ void ep3_add_projc(ep3_t r, const ep3_t p, const ep3_t q); void ep3_sub(ep3_t r, const ep3_t p, const ep3_t q); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension. + * Doubles a point represented in affine coordinates in an elliptic curve over + * a cubic extension. * * @param[out] r - the result. * @param[int] p - the point to double. @@ -1789,8 +1894,8 @@ void ep3_sub(ep3_t r, const ep3_t p, const ep3_t q); void ep3_dbl_basic(ep3_t r, const ep3_t p); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension and returns the computed slope. + * Doubles a point represented in affine coordinates in an elliptic curve over + * a cubic extension and returns the computed slope. * * @param[out] r - the result. * @param[out] s - the slope. @@ -1799,14 +1904,23 @@ void ep3_dbl_basic(ep3_t r, const ep3_t p); void ep3_dbl_slp_basic(ep3_t r, fp3_t s, const ep3_t p); /** - * Doubles a points represented in projective coordinates in an elliptic curve - * over a octic extension. + * Doubles a point represented in projective coordinates in an elliptic curve + * over a cubic extension. * * @param[out] r - the result. * @param[in] p - the point to double. */ void ep3_dbl_projc(ep3_t r, const ep3_t p); +/** + * Doubles a point represented in Jacobian coordinates in an elliptic curve + * over a cubic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +void ep3_dbl_jacob(ep3_t r, const ep3_t p); + /** * Multiplies a prime elliptic point by an integer using the binary method. * @@ -1872,7 +1986,7 @@ void ep3_mul_gen(ep3_t r, const bn_t k); void ep3_mul_dig(ep3_t r, const ep3_t p, const dig_t k); /** - * Multiplies a point in an elliptic curve over a octic extension field by + * Multiplies a point in an elliptic curve over a cubic extension field by * the curve cofactor or a small multiple for which a short vector exists. * In short, it takes a point in the curve to the large prime-order subgroup. * @@ -2105,10 +2219,10 @@ void ep3_map(ep3_t p, const uint8_t *msg, size_t len); /** * Computes a power of the Gailbraith-Lin-Scott homomorphism of a point * represented in affine coordinates on a twisted elliptic curve over a - * octic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). - * On the trace-zero group of a octic twist, consists of a power of the + * cubic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). + * On the trace-zero group of a cubic twist, consists of a power of the * Frobenius map of a point represented in affine coordinates in an elliptic - * curve over a octic exension. Computes Frob^i(P) = (p^i)P. + * curve over a cubic exension. Computes Frob^i(P) = (p^i)P. * * @param[out] r - the result in affine coordinates. * @param[in] p - a point in affine coordinates. @@ -2117,7 +2231,7 @@ void ep3_map(ep3_t p, const uint8_t *msg, size_t len); void ep3_frb(ep3_t r, const ep3_t p, int i); /** - * Compresses a point in an elliptic curve over a octic extension. + * Compresses a point in an elliptic curve over a cubic extension. * * @param[out] r - the result. * @param[in] p - the point to compress. @@ -2125,7 +2239,7 @@ void ep3_frb(ep3_t r, const ep3_t p, int i); void ep3_pck(ep3_t r, const ep3_t p); /** - * Decompresses a point in an elliptic curve over a octic extension. + * Decompresses a point in an elliptic curve over a cubic extension. * * @param[out] r - the result. * @param[in] p - the point to decompress. @@ -2134,12 +2248,12 @@ void ep3_pck(ep3_t r, const ep3_t p); int ep3_upk(ep3_t r, const ep3_t p); /** - * Initializes the elliptic curve over octic extension. + * Initializes the elliptic curve over quartic extension. */ void ep4_curve_init(void); /** - * Finalizes the elliptic curve over octic extension. + * Finalizes the elliptic curve over quartic extension. */ void ep4_curve_clean(void); @@ -2148,14 +2262,14 @@ void ep4_curve_clean(void); * * @return the 'a' coefficient of the elliptic curve. */ -void ep4_curve_get_a(fp4_t a); +fp2_t *ep4_curve_get_a(void); /** * Returns the 'b' coefficient of the currently configured elliptic curve. * * @param[out] b - the 'b' coefficient of the elliptic curve. */ -void ep4_curve_get_b(fp4_t b); +fp2_t *ep4_curve_get_b(void); /** * Returns a optimization identifier based on the 'a' coefficient of the curve. @@ -2171,6 +2285,22 @@ int ep4_curve_opt_a(void); */ int ep4_curve_opt_b(void); +/** + * Multiplies a field element by the a-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep4_curve_mul_a(fp4_t c, const fp4_t a); + +/** + * Multiplies a field element by the b-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep4_curve_mul_b(fp4_t c, const fp4_t a); + /** * Tests if the configured elliptic curve is a twist. * @@ -2207,7 +2337,7 @@ void ep4_curve_get_ord(bn_t n); void ep4_curve_get_cof(bn_t h); /** - * Configures an elliptic curve over a octic extension by its coefficients. + * Configures an elliptic curve over a quartic extension by its coefficients. * * @param[in] a - the 'a' coefficient of the curve. * @param[in] b - the 'b' coefficient of the curve. @@ -2273,13 +2403,13 @@ void ep4_rand(ep4_t p); void ep4_blind(ep4_t r, const ep4_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain prime elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ep4_rhs(fp4_t rhs, const ep4_t p); +void ep4_rhs(fp4_t rhs, const fp4_t x); /** * Tests if a point is in the curve. @@ -2306,7 +2436,7 @@ void ep4_print(const ep4_t p); /** * Returns the number of bytes necessary to store a prime elliptic curve point - * over a octic extension with optional point compression. + * over a quartic extension with optional point compression. * * @param[in] a - the prime field element. * @param[in] pack - the flag to indicate compression. @@ -2315,7 +2445,7 @@ void ep4_print(const ep4_t p); int ep4_size_bin(const ep4_t a, int pack); /** - * Reads a prime elliptic curve point over a octic extension from a byte + * Reads a prime elliptic curve point over a quartic extension from a byte * vector in big-endian format. * * @param[out] a - the result. @@ -2327,7 +2457,7 @@ int ep4_size_bin(const ep4_t a, int pack); void ep4_read_bin(ep4_t a, const uint8_t *bin, size_t len); /** - * Writes a prime elliptic curve pointer over a octic extension to a byte + * Writes a prime elliptic curve pointer over a quartic extension to a byte * vector in big-endian format with optional point compression. * * @param[out] bin - the byte vector. @@ -2340,7 +2470,7 @@ void ep4_write_bin(uint8_t *bin, size_t len, const ep4_t a, int pack); /** * Negates a point represented in affine coordinates in an elliptic curve over - * a octic extension. + * a quartic extension. * * @param[out] r - the result. * @param[out] p - the point to negate. @@ -2349,7 +2479,7 @@ void ep4_neg(ep4_t r, const ep4_t p); /** * Adds to points represented in affine coordinates in an elliptic curve over a - * octic extension. + * quartic extension. * * @param[out] r - the result. * @param[in] p - the first point to add. @@ -2359,7 +2489,7 @@ void ep4_add_basic(ep4_t r, const ep4_t p, const ep4_t q); /** * Adds to points represented in affine coordinates in an elliptic curve over a - * octic extension and returns the computed slope. + * quartic extension and returns the computed slope. * * @param[out] r - the result. * @param[out] s - the slope. @@ -2370,7 +2500,7 @@ void ep4_add_slp_basic(ep4_t r, fp4_t s, const ep4_t p, const ep4_t q); /** * Adds two points represented in projective coordinates in an elliptic curve - * over a octic extension. + * over a quartic extension. * * @param[out] r - the result. * @param[in] p - the first point to add. @@ -2378,8 +2508,18 @@ void ep4_add_slp_basic(ep4_t r, fp4_t s, const ep4_t p, const ep4_t q); */ void ep4_add_projc(ep4_t r, const ep4_t p, const ep4_t q); +/** + * Adds two points represented in Jacobian coordinates in an elliptic curve + * over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep4_add_jacob(ep4_t r, const ep4_t p, const ep4_t q); + /** - * Subtracts a point in an elliptic curve over a octic extension from + * Subtracts a point in an elliptic curve over a quartic extension from * another. * * @param[out] r - the result. @@ -2389,8 +2529,8 @@ void ep4_add_projc(ep4_t r, const ep4_t p, const ep4_t q); void ep4_sub(ep4_t r, const ep4_t p, const ep4_t q); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension. + * Doubles a point represented in affine coordinates in an elliptic curve over + * a quartic extension. * * @param[out] r - the result. * @param[int] p - the point to double. @@ -2398,8 +2538,8 @@ void ep4_sub(ep4_t r, const ep4_t p, const ep4_t q); void ep4_dbl_basic(ep4_t r, const ep4_t p); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension and returns the computed slope. + * Doubles a point represented in affine coordinates in an elliptic curve over + * a quartic extension and returns the computed slope. * * @param[out] r - the result. * @param[out] s - the slope. @@ -2408,14 +2548,23 @@ void ep4_dbl_basic(ep4_t r, const ep4_t p); void ep4_dbl_slp_basic(ep4_t r, fp4_t s, const ep4_t p); /** - * Doubles a points represented in projective coordinates in an elliptic curve - * over a octic extension. + * Doubles a point represented in projective coordinates in an elliptic curve + * over a quartic extension. * * @param[out] r - the result. * @param[in] p - the point to double. */ void ep4_dbl_projc(ep4_t r, const ep4_t p); +/** + * Doubles a point represented in Jacobian coordinates in an elliptic curve + * over a quartic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +void ep4_dbl_jacob(ep4_t r, const ep4_t p); + /** * Multiplies a prime elliptic point by an integer using the binary method. * @@ -2482,7 +2631,7 @@ void ep4_mul_dig(ep4_t r, const ep4_t p, const dig_t k); /** - * Multiplies a point in an elliptic curve over a octic extension field by + * Multiplies a point in an elliptic curve over a quartic extension field by * the curve cofactor or a small multiple for which a short vector exists. * In short, it takes a point in the curve to the large prime-order subgroup. * @@ -2704,7 +2853,7 @@ void ep4_norm(ep4_t r, const ep4_t p); void ep4_norm_sim(ep4_t *r, const ep4_t *t, int n); /** - * Maps a byte array to a point in an elliptic curve over a octic extension. + * Maps a byte array to a point in an elliptic curve over a quartic extension. * * @param[out] p - the result. * @param[in] msg - the byte array to map. @@ -2715,10 +2864,10 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len); /** * Computes a power of the Gailbraith-Lin-Scott homomorphism of a point * represented in affine coordinates on a twisted elliptic curve over a - * octic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). - * On the trace-zero group of a octic twist, consists of a power of the + * quartic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). + * On the trace-zero group of a quartic twist, consists of a power of the * Frobenius map of a point represented in affine coordinates in an elliptic - * curve over a octic exension. Computes Frob^i(P) = (p^i)P. + * curve over a quartic exension. Computes Frob^i(P) = (p^i)P. * * @param[out] r - the result in affine coordinates. * @param[in] p - a point in affine coordinates. @@ -2727,7 +2876,7 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len); void ep4_frb(ep4_t r, const ep4_t p, int i); /** - * Compresses a point in an elliptic curve over a octic extension. + * Compresses a point in an elliptic curve over a quartic extension. * * @param[out] r - the result. * @param[in] p - the point to compress. @@ -2735,7 +2884,7 @@ void ep4_frb(ep4_t r, const ep4_t p, int i); void ep4_pck(ep4_t r, const ep4_t p); /** - * Decompresses a point in an elliptic curve over a octic extension. + * Decompresses a point in an elliptic curve over a quartic extension. * * @param[out] r - the result. * @param[in] p - the point to decompress. @@ -2758,14 +2907,14 @@ void ep8_curve_clean(void); * * @return the 'a' coefficient of the elliptic curve. */ -void ep8_curve_get_a(fp8_t a); +fp4_t *ep8_curve_get_a(void); /** * Returns the 'b' coefficient of the currently configured elliptic curve. * * @param[out] b - the 'b' coefficient of the elliptic curve. */ -void ep8_curve_get_b(fp8_t b); +fp4_t *ep8_curve_get_b(void); /** * Returns a optimization identifier based on the 'a' coefficient of the curve. @@ -2781,6 +2930,22 @@ int ep8_curve_opt_a(void); */ int ep8_curve_opt_b(void); +/** + * Multiplies a field element by the a-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep8_curve_mul_a(fp8_t c, const fp8_t a); + +/** + * Multiplies a field element by the b-coefficient of the curve. + * + * @param[out] c - the result. + * @param[in] a - the field element to multiply. + */ +void ep8_curve_mul_b(fp8_t c, const fp8_t a); + /** * Tests if the configured elliptic curve is a twist. * @@ -2817,7 +2982,7 @@ void ep8_curve_get_ord(bn_t n); void ep8_curve_get_cof(bn_t h); /** - * Configures an elliptic curve over a octic extension by its coefficients. + * Configures an elliptic curve over an octic extension by its coefficients. * * @param[in] a - the 'a' coefficient of the curve. * @param[in] b - the 'b' coefficient of the curve. @@ -2883,13 +3048,13 @@ void ep8_rand(ep8_t p); void ep8_blind(ep8_t r, const ep8_t p); /** - * Computes the right-hand side of the elliptic curve equation at a certain - * elliptic curve point. + * Computes the right-hand side of the elliptic curve equation at the + * x-coordinate of a certain prime elliptic curve point. * * @param[out] rhs - the result. - * @param[in] p - the point. + * @param[in] x - the x-coordinate of the point. */ -void ep8_rhs(fp8_t rhs, const ep8_t p); +void ep8_rhs(fp8_t rhs, const fp8_t x); /** * Tests if a point is in the curve. @@ -2916,7 +3081,7 @@ void ep8_print(const ep8_t p); /** * Returns the number of bytes necessary to store a prime elliptic curve point - * over a octic extension with optional point compression. + * over an octic extension with optional point compression. * * @param[in] a - the prime field element. * @param[in] pack - the flag to indicate compression. @@ -2925,7 +3090,7 @@ void ep8_print(const ep8_t p); int ep8_size_bin(const ep8_t a, int pack); /** - * Reads a prime elliptic curve point over a octic extension from a byte + * Reads a prime elliptic curve point over an octic extension from a byte * vector in big-endian format. * * @param[out] a - the result. @@ -2937,7 +3102,7 @@ int ep8_size_bin(const ep8_t a, int pack); void ep8_read_bin(ep8_t a, const uint8_t *bin, size_t len); /** - * Writes a prime elliptic curve pointer over a octic extension to a byte + * Writes a prime elliptic curve pointer over an octic extension to a byte * vector in big-endian format with optional point compression. * * @param[out] bin - the byte vector. @@ -2950,7 +3115,7 @@ void ep8_write_bin(uint8_t *bin, size_t len, const ep8_t a, int pack); /** * Negates a point represented in affine coordinates in an elliptic curve over - * a octic extension. + * an octic extension. * * @param[out] r - the result. * @param[out] p - the point to negate. @@ -2980,7 +3145,7 @@ void ep8_add_slp_basic(ep8_t r, fp8_t s, const ep8_t p, const ep8_t q); /** * Adds two points represented in projective coordinates in an elliptic curve - * over a octic extension. + * over an octic extension. * * @param[out] r - the result. * @param[in] p - the first point to add. @@ -2988,8 +3153,18 @@ void ep8_add_slp_basic(ep8_t r, fp8_t s, const ep8_t p, const ep8_t q); */ void ep8_add_projc(ep8_t r, const ep8_t p, const ep8_t q); +/** + * Adds two points represented in Jacobian coordinates in an elliptic curve + * over an octic extension. + * + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. + */ +void ep8_add_jacob(ep8_t r, const ep8_t p, const ep8_t q); + /** - * Subtracts a point in an elliptic curve over a octic extension from + * Subtracts a point in an elliptic curve over an octic extension from * another. * * @param[out] r - the result. @@ -2999,8 +3174,8 @@ void ep8_add_projc(ep8_t r, const ep8_t p, const ep8_t q); void ep8_sub(ep8_t r, const ep8_t p, const ep8_t q); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension. + * Doubles a point represented in affine coordinates in an elliptic curve over + * an octic extension. * * @param[out] r - the result. * @param[int] p - the point to double. @@ -3008,8 +3183,8 @@ void ep8_sub(ep8_t r, const ep8_t p, const ep8_t q); void ep8_dbl_basic(ep8_t r, const ep8_t p); /** - * Doubles a points represented in affine coordinates in an elliptic curve over - * a octic extension and returns the computed slope. + * Doubles a point represented in affine coordinates in an elliptic curve over + * an octic extension and returns the computed slope. * * @param[out] r - the result. * @param[out] s - the slope. @@ -3018,14 +3193,23 @@ void ep8_dbl_basic(ep8_t r, const ep8_t p); void ep8_dbl_slp_basic(ep8_t r, fp8_t s, const ep8_t p); /** - * Doubles a points represented in projective coordinates in an elliptic curve - * over a octic extension. + * Doubles a point represented in projective coordinates in an elliptic curve + * over an octic extension. * * @param[out] r - the result. * @param[in] p - the point to double. */ void ep8_dbl_projc(ep8_t r, const ep8_t p); +/** + * Doubles a point represented in Jacobian coordinates in an elliptic curve + * over an octic extension. + * + * @param[out] r - the result. + * @param[in] p - the point to double. + */ +void ep8_dbl_jacob(ep8_t r, const ep8_t p); + /** * Multiplies a prime elliptic point by an integer using the binary method. * @@ -3092,7 +3276,7 @@ void ep8_mul_dig(ep8_t r, const ep8_t p, const dig_t k); /** - * Multiplies a point in an elliptic curve over a octic extension field by + * Multiplies a point in an elliptic curve over an octic extension field by * the curve cofactor or a small multiple for which a short vector exists. * In short, it takes a point in the curve to the large prime-order subgroup. * @@ -3314,7 +3498,7 @@ void ep8_norm(ep8_t r, const ep8_t p); void ep8_norm_sim(ep8_t *r, const ep8_t *t, int n); /** - * Maps a byte array to a point in an elliptic curve over a octic extension. + * Maps a byte array to a point in an elliptic curve over an octic extension. * * @param[out] p - the result. * @param[in] msg - the byte array to map. @@ -3326,9 +3510,9 @@ void ep8_map(ep8_t p, const uint8_t *msg, size_t len); * Computes a power of the Gailbraith-Lin-Scott homomorphism of a point * represented in affine coordinates on a twisted elliptic curve over a * octic exension. That is, Psi^i(P) = Twist(P)(Frob^i(unTwist(P)). - * On the trace-zero group of a octic twist, consists of a power of the + * On the trace-zero group of an octic twist, consists of a power of the * Frobenius map of a point represented in affine coordinates in an elliptic - * curve over a octic exension. Computes Frob^i(P) = (p^i)P. + * curve over an octic exension. Computes Frob^i(P) = (p^i)P. * * @param[out] r - the result in affine coordinates. * @param[in] p - a point in affine coordinates. @@ -3337,7 +3521,7 @@ void ep8_map(ep8_t p, const uint8_t *msg, size_t len); void ep8_frb(ep8_t r, const ep8_t p, int i); /** - * Compresses a point in an elliptic curve over a octic extension. + * Compresses a point in an elliptic curve over an octic extension. * * @param[out] r - the result. * @param[in] p - the point to compress. @@ -3345,7 +3529,7 @@ void ep8_frb(ep8_t r, const ep8_t p, int i); void ep8_pck(ep8_t r, const ep8_t p); /** - * Decompresses a point in an elliptic curve over a octic extension. + * Decompresses a point in an elliptic curve over an octic extension. * * @param[out] r - the result. * @param[in] p - the point to decompress. diff --git a/include/relic_fp.h b/include/relic_fp.h index 8dabbf887..2ae5474af 100644 --- a/include/relic_fp.h +++ b/include/relic_fp.h @@ -156,8 +156,6 @@ enum { K18_638, /** 638-bit prime for SG curve with embedding degree 18. */ SG18_638, - /** 765-bit prime for new family with embedding degree 16. */ - N16_765, /** 765-bit prime for FM curve with embedding degree 16. */ FM16_765, /** 766-bit prime for KSS curve with embedding degree 16. */ @@ -168,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. */ @@ -668,6 +668,15 @@ void fp_param_get_sps(int *s, int *len); */ void fp_copy(fp_t c, const fp_t a); +/** + * Conditionally copies a field element to another field element. + * + * @param[out] c - the destination. + * @paraim[in] a - the source. + * @param[in] bit - the condition bit to evaluate. + */ +void fp_copy_sec(fp_t c, const fp_t a, dig_t bit); + /** * Assigns zero to a prime field element. * diff --git a/include/relic_fpx.h b/include/relic_fpx.h index c0f5f9c62..f06eb56fe 100644 --- a/include/relic_fpx.h +++ b/include/relic_fpx.h @@ -338,7 +338,7 @@ typedef fp18_t fp54_t[3]; /** * Multiplies a quadratic extension field by the quadratic/cubic non-residue. * Computes C = A * E, where E is a non-square/non-cube in the quadratic - * extension. + * extension field. * * @param[out] C - the result. * @param[in] A - the quadratic extension field element to multiply. @@ -1398,6 +1398,15 @@ int fp2_field_get_qnr(void); */ void fp2_copy(fp2_t c, const fp2_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the quadratic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp2_copy_sec(fp2_t c, const fp2_t a, dig_t bit); + /** * Assigns zero to a quadratic extension field element. * @@ -1800,6 +1809,15 @@ int fp3_field_get_cnr(void); */ void fp3_copy(fp3_t c, const fp3_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the cubic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp3_copy_sec(fp3_t c, const fp3_t a, dig_t bit); + /** * Assigns zero to a cubic extension field element. * @@ -2107,10 +2125,19 @@ void fp4_field_init(void); * Copies the second argument to the first argument. * * @param[out] c - the result. - * @param[in] a - the sextic extension field element to copy. + * @param[in] a - the quartic extension field element to copy. */ void fp4_copy(fp4_t c, const fp4_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the quartic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp4_copy_sec(fp4_t c, const fp4_t a, dig_t bit); + /** * Assigns zero to a quartic extension field element. * @@ -2417,6 +2444,16 @@ int fp4_srt(fp4_t c, const fp4_t a); */ void fp6_copy(fp6_t c, const fp6_t a); + +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the sextic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp6_copy_sec(fp6_t c, const fp6_t a, dig_t bit); + /** * Assigns zero to a sextic extension field element. * @@ -2651,6 +2688,15 @@ void fp8_field_init(void); */ void fp8_copy(fp8_t c, const fp8_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the octic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp8_copy_sec(fp8_t c, const fp8_t a, dig_t bit); + /** * Assigns zero to an octic extension field element. * @@ -2708,9 +2754,10 @@ void fp8_read_bin(fp8_t a, const uint8_t *bin, size_t len); * @param[out] bin - the byte vector. * @param[in] len - the buffer capacity. * @param[in] a - the extension field element to write. + * @param[in] pack - the flag to indicate compression. * @throw ERR_NO_BUFFER - if the buffer capacity is not correct. */ -void fp8_write_bin(uint8_t *bin, size_t len, const fp8_t a); +void fp8_write_bin(uint8_t *bin, size_t len, const fp8_t a, int pack); /** * Returns the result of a comparison between two octic extension field @@ -2937,6 +2984,18 @@ void fp8_exp_dig(fp8_t c, const fp8_t a, dig_t b); */ void fp8_exp_cyc(fp8_t c, const fp8_t a, const bn_t b); +/** + * Computes a power of two cyclotomic octic extension field elements. + * + * @param[out] e - the result. + * @param[in] a - the first element to exponentiate. + * @param[in] b - the first exponent. + * @param[in] c - the second element to exponentiate. + * @param[in] d - the second exponent. + */ +void fp8_exp_cyc_sim(fp8_t e, const fp8_t a, const bn_t b, const fp8_t c, + const bn_t d); + /** * Computes a power of the Frobenius endomorphism of an octic extension field * element. Computes c = a^p^i. @@ -2973,6 +3032,15 @@ int fp8_srt(fp8_t c, const fp8_t a); */ void fp9_copy(fp9_t c, const fp9_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the nonic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp9_copy_sec(fp9_t c, const fp9_t a, dig_t bit); + /** * Assigns zero to a nonic extension field element. * @@ -3211,6 +3279,15 @@ void fp9_frb(fp9_t c, const fp9_t a, int i); */ void fp12_copy(fp12_t c, const fp12_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the dodecic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp12_copy_sec(fp12_t c, const fp12_t a, dig_t bit); + /** * Assigns zero to a dodecic extension field element. * @@ -3628,6 +3705,15 @@ void fp16_field_init(void); */ void fp16_copy(fp16_t c, const fp16_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the sextadecic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp16_copy_sec(fp16_t c, const fp16_t a, dig_t bit); + /** * Assigns zero to an sextadecic extension field element. * @@ -3975,6 +4061,15 @@ int fp16_srt(fp16_t c, const fp16_t a); */ void fp18_copy(fp18_t c, const fp18_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the octdecic extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp18_copy_sec(fp18_t c, const fp18_t a, dig_t bit); + /** * Assigns zero to an octdecic extension field element. * @@ -4387,6 +4482,15 @@ int fp18_upk_max(fp18_t c, const fp18_t a); */ void fp24_copy(fp24_t c, const fp24_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the 24-degree extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp24_copy_sec(fp24_t c, const fp24_t a, dig_t bit); + /** * Assigns zero to a 24-degree extension field element. * @@ -4770,6 +4874,15 @@ int fp24_upk(fp24_t c, const fp24_t a); */ void fp48_copy(fp48_t c, const fp48_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the 48-degree extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp48_copy_sec(fp48_t c, const fp48_t a, dig_t bit); + /** * Assigns zero to a 48-extension field element. * @@ -5137,6 +5250,15 @@ int fp48_upk(fp48_t c, const fp48_t a); */ void fp54_copy(fp54_t c, const fp54_t a); +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] c - the result. + * @param[in] a - the 54-degree extension field element to copy. + * @param[in] bit - the condition bit to evaluate. + */ +void fp54_copy_sec(fp54_t c, const fp54_t a, dig_t bit); + /** * Assigns zero to a 54-extension field element. * diff --git a/include/relic_label.h b/include/relic_label.h index 8f8dabb1e..3e6dc321a 100644 --- a/include/relic_label.h +++ b/include/relic_label.h @@ -134,7 +134,7 @@ #undef util_conv_little #undef util_conv_char #undef util_bits_dig -#undef util_cmp_const +#undef util_cmp_sec #undef util_perm #undef util_printf #undef util_print_dig @@ -144,7 +144,7 @@ #define util_conv_little RLC_PREFIX(util_conv_little) #define util_conv_char RLC_PREFIX(util_conv_char) #define util_bits_dig RLC_PREFIX(util_bits_dig) -#define util_cmp_const RLC_PREFIX(util_cmp_const) +#define util_cmp_sec RLC_PREFIX(util_cmp_sec) #define util_perm RLC_PREFIX(util_perm) #define util_printf RLC_PREFIX(util_printf) #define util_print_dig RLC_PREFIX(util_print_dig) @@ -158,10 +158,10 @@ #undef dv_print #undef dv_zero #undef dv_copy -#undef dv_copy_cond -#undef dv_swap_cond +#undef dv_copy_sec +#undef dv_swap_sec #undef dv_cmp -#undef dv_cmp_const +#undef dv_cmp_sec #undef dv_new_dynam #undef dv_free_dynam #undef dv_lshd @@ -170,10 +170,10 @@ #define dv_print RLC_PREFIX(dv_print) #define dv_zero RLC_PREFIX(dv_zero) #define dv_copy RLC_PREFIX(dv_copy) -#define dv_copy_cond RLC_PREFIX(dv_copy_cond) -#define dv_swap_cond RLC_PREFIX(dv_swap_cond) +#define dv_copy_sec RLC_PREFIX(dv_copy_sec) +#define dv_swap_sec RLC_PREFIX(dv_swap_sec) #define dv_cmp RLC_PREFIX(dv_cmp) -#define dv_cmp_const RLC_PREFIX(dv_cmp_const) +#define dv_cmp_sec RLC_PREFIX(dv_cmp_sec) #define dv_new_dynam RLC_PREFIX(dv_new_dynam) #define dv_free_dynam RLC_PREFIX(dv_free_dynam) #define dv_lshd RLC_PREFIX(dv_lshd) @@ -489,6 +489,7 @@ #undef fp_prime_get_par_sps #undef fp_param_get_sps #undef fp_copy +#undef fp_copy_sec #undef fp_zero #undef fp_is_zero #undef fp_is_even @@ -586,6 +587,7 @@ #define fp_prime_get_par_sps RLC_PREFIX(fp_prime_get_par_sps) #define fp_param_get_sps RLC_PREFIX(fp_param_get_sps) #define fp_copy RLC_PREFIX(fp_copy) +#define fp_copy_sec RLC_PREFIX(fp_copy_sec) #define fp_zero RLC_PREFIX(fp_zero) #define fp_is_zero RLC_PREFIX(fp_is_zero) #define fp_is_even RLC_PREFIX(fp_is_even) @@ -919,10 +921,8 @@ #undef ep_curve_get_v2 #undef ep_curve_opt_a #undef ep_curve_opt_b -#undef ep_curve_opt_b3 #undef ep_curve_mul_a #undef ep_curve_mul_b -#undef ep_curve_mul_b3 #undef ep_curve_is_endom #undef ep_curve_is_super #undef ep_curve_is_pairf @@ -944,7 +944,7 @@ #undef ep_param_get #undef ep_param_print #undef ep_param_level -#undef ep_param_embed +#undef ep_curve_embed #undef ep_is_infty #undef ep_set_infty #undef ep_copy @@ -1014,10 +1014,8 @@ #define ep_curve_get_v2 RLC_PREFIX(ep_curve_get_v2) #define ep_curve_opt_a RLC_PREFIX(ep_curve_opt_a) #define ep_curve_opt_b RLC_PREFIX(ep_curve_opt_b) -#define ep_curve_opt_b3 RLC_PREFIX(ep_curve_opt_b3) #define ep_curve_mul_a RLC_PREFIX(ep_curve_mul_a) #define ep_curve_mul_b RLC_PREFIX(ep_curve_mul_b) -#define ep_curve_mul_b3 RLC_PREFIX(ep_curve_mul_b3) #define ep_curve_is_endom RLC_PREFIX(ep_curve_is_endom) #define ep_curve_is_super RLC_PREFIX(ep_curve_is_super) #define ep_curve_is_pairf RLC_PREFIX(ep_curve_is_pairf) @@ -1039,7 +1037,7 @@ #define ep_param_get RLC_PREFIX(ep_param_get) #define ep_param_print RLC_PREFIX(ep_param_print) #define ep_param_level RLC_PREFIX(ep_param_level) -#define ep_param_embed RLC_PREFIX(ep_param_embed) +#define ep_curve_embed RLC_PREFIX(ep_curve_embed) #define ep_is_infty RLC_PREFIX(ep_is_infty) #define ep_set_infty RLC_PREFIX(ep_set_infty) #define ep_copy RLC_PREFIX(ep_copy) @@ -1402,6 +1400,8 @@ #undef ep2_curve_get_b #undef ep2_curve_opt_a #undef ep2_curve_opt_b +#undef ep2_curve_mul_a +#undef ep2_curve_mul_b #undef ep2_curve_is_twist #undef ep2_curve_is_ctmap #undef ep2_curve_get_gen @@ -1428,10 +1428,12 @@ #undef ep2_add_basic #undef ep2_add_slp_basic #undef ep2_add_projc +#undef ep2_add_jacob #undef ep2_sub #undef ep2_dbl_basic #undef ep2_dbl_slp_basic #undef ep2_dbl_projc +#undef ep2_dbl_jacob #undef ep2_mul_basic #undef ep2_mul_slide #undef ep2_mul_monty @@ -1474,6 +1476,8 @@ #define ep2_curve_get_b RLC_PREFIX(ep2_curve_get_b) #define ep2_curve_opt_a RLC_PREFIX(ep2_curve_opt_a) #define ep2_curve_opt_b RLC_PREFIX(ep2_curve_opt_b) +#define ep2_curve_mul_a RLC_PREFIX(ep2_curve_mul_a) +#define ep2_curve_mul_b RLC_PREFIX(ep2_curve_mul_b) #define ep2_curve_is_twist RLC_PREFIX(ep2_curve_is_twist) #define ep2_curve_is_ctmap RLC_PREFIX(ep2_curve_is_ctmap) #define ep2_curve_get_gen RLC_PREFIX(ep2_curve_get_gen) @@ -1500,10 +1504,12 @@ #define ep2_add_basic RLC_PREFIX(ep2_add_basic) #define ep2_add_slp_basic RLC_PREFIX(ep2_add_slp_basic) #define ep2_add_projc RLC_PREFIX(ep2_add_projc) +#define ep2_add_jacob RLC_PREFIX(ep2_add_jacob) #define ep2_sub RLC_PREFIX(ep2_sub) #define ep2_dbl_basic RLC_PREFIX(ep2_dbl_basic) #define ep2_dbl_slp_basic RLC_PREFIX(ep2_dbl_slp_basic) #define ep2_dbl_projc RLC_PREFIX(ep2_dbl_projc) +#define ep2_dbl_jacob RLC_PREFIX(ep2_dbl_jacob) #define ep2_mul_basic RLC_PREFIX(ep2_mul_basic) #define ep2_mul_slide RLC_PREFIX(ep2_mul_slide) #define ep2_mul_monty RLC_PREFIX(ep2_mul_monty) @@ -2027,6 +2033,7 @@ #undef fp2_field_init #undef fp2_field_get_qnr #undef fp2_copy +#undef fp2_copy_sec #undef fp2_zero #undef fp2_is_zero #undef fp2_rand @@ -2073,6 +2080,7 @@ #define fp2_field_init RLC_PREFIX(fp2_field_init) #define fp2_field_get_qnr RLC_PREFIX(fp2_field_get_qnr) #define fp2_copy RLC_PREFIX(fp2_copy) +#define fp2_copy_sec RLC_PREFIX(fp2_copy_sec) #define fp2_zero RLC_PREFIX(fp2_zero) #define fp2_is_zero RLC_PREFIX(fp2_is_zero) #define fp2_rand RLC_PREFIX(fp2_rand) @@ -2157,6 +2165,7 @@ #undef fp3_field_init #undef fp3_field_get_cnr #undef fp3_copy +#undef fp3_copy_sec #undef fp3_zero #undef fp3_is_zero #undef fp3_rand @@ -2194,6 +2203,7 @@ #define fp3_field_init RLC_PREFIX(fp3_field_init) #define fp3_field_get_cnr RLC_PREFIX(fp3_field_get_cnr) #define fp3_copy RLC_PREFIX(fp3_copy) +#define fp3_copy_sec RLC_PREFIX(fp3_copy_sec) #define fp3_zero RLC_PREFIX(fp3_zero) #define fp3_is_zero RLC_PREFIX(fp3_is_zero) #define fp3_rand RLC_PREFIX(fp3_rand) @@ -2266,6 +2276,7 @@ #undef fp4_field_init #undef fp4_copy +#undef fp4_copy_sec #undef fp4_zero #undef fp4_is_zero #undef fp4_rand @@ -2302,6 +2313,7 @@ #define fp4_field_init RLC_PREFIX(fp4_field_init) #define fp4_copy RLC_PREFIX(fp4_copy) +#define fp4_copy_sec RLC_PREFIX(fp4_copy_sec) #define fp4_zero RLC_PREFIX(fp4_zero) #define fp4_is_zero RLC_PREFIX(fp4_is_zero) #define fp4_rand RLC_PREFIX(fp4_rand) @@ -2337,6 +2349,7 @@ #define fp4_srt RLC_PREFIX(fp4_srt) #undef fp6_copy +#undef fp6_copy_sec #undef fp6_zero #undef fp6_is_zero #undef fp6_rand @@ -2364,6 +2377,7 @@ #undef fp6_frb #define fp6_copy RLC_PREFIX(fp6_copy) +#define fp6_copy_sec RLC_PREFIX(fp6_copy_sec) #define fp6_zero RLC_PREFIX(fp6_zero) #define fp6_is_zero RLC_PREFIX(fp6_is_zero) #define fp6_rand RLC_PREFIX(fp6_rand) @@ -2392,6 +2406,7 @@ #undef fp8_field_init #undef fp8_copy +#undef fp8_copy_sec #undef fp8_zero #undef fp8_is_zero #undef fp8_rand @@ -2430,6 +2445,7 @@ #define fp8_field_init RLC_PREFIX(fp8_field_init) #define fp8_copy RLC_PREFIX(fp8_copy) +#define fp8_copy_sec RLC_PREFIX(fp8_copy_sec) #define fp8_zero RLC_PREFIX(fp8_zero) #define fp8_is_zero RLC_PREFIX(fp8_is_zero) #define fp8_rand RLC_PREFIX(fp8_rand) @@ -2467,6 +2483,7 @@ #define fp8_srt RLC_PREFIX(fp8_srt) #undef fp9_copy +#undef fp9_copy_sec #undef fp9_zero #undef fp9_is_zero #undef fp9_rand @@ -2495,6 +2512,7 @@ #undef fp9_frb #define fp9_copy RLC_PREFIX(fp9_copy) +#define fp9_copy_sec RLC_PREFIX(fp9_copy_sec) #define fp9_zero RLC_PREFIX(fp9_zero) #define fp9_is_zero RLC_PREFIX(fp9_is_zero) #define fp9_rand RLC_PREFIX(fp9_rand) @@ -2523,6 +2541,7 @@ #define fp9_frb RLC_PREFIX(fp9_frb) #undef fp12_copy +#undef fp12_copy_sec #undef fp12_zero #undef fp12_is_zero #undef fp12_rand @@ -2569,6 +2588,7 @@ #undef fp12_upk_max #define fp12_copy RLC_PREFIX(fp12_copy) +#define fp12_copy_sec RLC_PREFIX(fp12_copy_sec) #define fp12_zero RLC_PREFIX(fp12_zero) #define fp12_is_zero RLC_PREFIX(fp12_is_zero) #define fp12_rand RLC_PREFIX(fp12_rand) @@ -2615,6 +2635,7 @@ #define fp12_upk_max RLC_PREFIX(fp12_upk_max) #undef fp18_copy +#undef fp18_copy_sec #undef fp18_zero #undef fp18_is_zero #undef fp18_rand @@ -2661,6 +2682,7 @@ #undef fp18_upk_max #define fp18_copy RLC_PREFIX(fp18_copy) +#define fp18_copy_sec RLC_PREFIX(fp18_copy_sec) #define fp18_zero RLC_PREFIX(fp18_zero) #define fp18_is_zero RLC_PREFIX(fp18_is_zero) #define fp18_rand RLC_PREFIX(fp18_rand) @@ -2707,6 +2729,7 @@ #define fp18_upk_max RLC_PREFIX(fp18_upk_max) #undef fp24_copy +#undef fp24_copy_sec #undef fp24_zero #undef fp24_is_zero #undef fp24_rand @@ -2750,6 +2773,7 @@ #undef fp24_upk #define fp24_copy RLC_PREFIX(fp24_copy) +#define fp24_copy_sec RLC_PREFIX(fp24_copy_sec) #define fp24_zero RLC_PREFIX(fp24_zero) #define fp24_is_zero RLC_PREFIX(fp24_is_zero) #define fp24_rand RLC_PREFIX(fp24_rand) @@ -2793,6 +2817,7 @@ #define fp24_upk RLC_PREFIX(fp24_upk) #undef fp48_copy +#undef fp48_copy_sec #undef fp48_zero #undef fp48_is_zero #undef fp48_rand @@ -2834,6 +2859,7 @@ #undef fp48_upk #define fp48_copy RLC_PREFIX(fp48_copy) +#define fp48_copy_sec RLC_PREFIX(fp48_copy_sec) #define fp48_zero RLC_PREFIX(fp48_zero) #define fp48_is_zero RLC_PREFIX(fp48_is_zero) #define fp48_rand RLC_PREFIX(fp48_rand) @@ -2875,6 +2901,7 @@ #define fp48_upk RLC_PREFIX(fp48_upk) #undef fp54_copy +#undef fp54_copy_sec #undef fp54_zero #undef fp54_is_zero #undef fp54_rand @@ -2914,6 +2941,7 @@ #undef fp54_upk #define fp54_copy RLC_PREFIX(fp54_copy) +#define fp54_copy_sec RLC_PREFIX(fp54_copy_sec) #define fp54_zero RLC_PREFIX(fp54_zero) #define fp54_is_zero RLC_PREFIX(fp54_is_zero) #define fp54_rand RLC_PREFIX(fp54_rand) diff --git a/include/relic_pc.h b/include/relic_pc.h index 62a0bfe2a..2fe17788e 100644 --- a/include/relic_pc.h +++ b/include/relic_pc.h @@ -84,12 +84,15 @@ #elif FP_PRIME == 330 || FP_PRIME == 765 || FP_PRIME == 766 #define RLC_GT_LOWER fp16_ #define RLC_GT_EMBED 16 +#elif FP_PRIME == 544 +#define RLC_GT_LOWER fp8_ +#define RLC_GT_EMBED 8 #else #define RLC_GT_LOWER fp12_ #define RLC_GT_EMBED 12 #endif -#else +#else /* FP_PRIME >= 1536*/ #define RLC_G1_LOWER ep_ #define RLC_G1_UPPER EP #define RLC_G2_LOWER ep_ @@ -406,6 +409,15 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; */ #define gt_copy(C, A) RLC_CAT(RLC_GT_LOWER, copy)(C, A) +/** + * Conditionally copies the second argument to the first argument. + * + * @param[out] C - the result. + * @param[in] A - the element to copy. + * @param[in] B - the condition bit to evaluate. + */ +#define gt_copy_sec(C, A, B) RLC_CAT(RLC_GT_LOWER, copy_sec)(C, A, B) + /** * Compares two elements from G_1. * @@ -729,7 +741,16 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; * @param[in] P - the element to multiply. * @param[in] K - the secret scalar. */ -#define g1_mul_key(R, P, K) RLC_CAT(RLC_G1_LOWER, mul_lwreg)(R, P, K) +#define g1_mul_sec(R, P, K) RLC_CAT(RLC_G1_LOWER, mul_lwreg)(R, P, K) + +/** + * Multiplies an element from G_2 by a secret scalar. Computes R = [k]P. + * + * @param[out] R - the result. + * @param[in] P - the element to multiply. + * @param[in] K - the secret scalar. + */ +#define g2_mul_sec(R, P, K) RLC_CAT(RLC_G2_LOWER, mul_lwreg)(R, P, K) /** * Multiplies an element from a larger group containing G_1 by a scalar. @@ -910,7 +931,7 @@ typedef RLC_CAT(RLC_GT_LOWER, t) gt_t; #if FP_PRIME <= 1536 #define gt_frb(C, A, I) RLC_CAT(RLC_GT_LOWER, frb)(C, A, I) #else -#define gt_frb(C, A, I) (A) +#define gt_frb(C, A, I) RLC_CAT(RLC_GT_LOWER, copy)(C, A) #endif /** @@ -1030,6 +1051,15 @@ void g2_mul_gen(g2_t r, const bn_t k); */ void gt_exp(gt_t c, const gt_t a, const bn_t b); +/** + * Exponentiates an element from G_T by a secret integer. Computes c = a^b. + * + * @param[out] c - the result. + * @param[in] a - the element to exponentiate. + * @param[in] b - the integer exponent. + */ +void gt_exp_sec(gt_t c, const gt_t a, const bn_t b); + /** * Exponentiates an element from G_T by a small integer. Computes c = a^b. * diff --git a/include/relic_pp.h b/include/relic_pp.h index 2077bb691..541bf2953 100644 --- a/include/relic_pp.h +++ b/include/relic_pp.h @@ -493,7 +493,7 @@ #define pp_map_k1(R, P, Q) pp_map_tatep_k1(R, P, Q) #endif -/**pp_map +/** * Computes a pairing of two prime elliptic curve points defined on an elliptic * curves of embedding degree 2. Computes e(P, Q). * @@ -509,6 +509,16 @@ #define pp_map_k2(R, P, Q) pp_map_tatep_k2(R, P, Q) #endif +/** + * Computes a pairing of two prime elliptic curve points defined on an elliptic + * curves of embedding degree 8. Computes e(P, Q). + * + * @param[out] R - the result. + * @param[in] P - the first elliptic curve point. + * @param[in] Q - the second elliptic curve point. + */ +#define pp_map_k8(R, P, Q) pp_map_oatep_k8(R, P, Q) + /** * Computes a pairing of two prime elliptic curve points defined on an elliptic * curve of embedding degree 12. Computes e(P, Q). @@ -587,6 +597,17 @@ #define pp_map_sim_k2(R, P, Q, M) pp_map_sim_tatep_k2(R, P, Q, M) #endif +/** + * Computes a multi-pairing of elliptic curve points defined on an elliptic + * curve of embedding degree 8. Computes \prod e(P_i, Q_i). + * + * @param[out] R - the result. + * @param[in] P - the first pairing arguments. + * @param[in] Q - the second pairing arguments. + * @param[in] M - the number of pairings to evaluate. + */ +#define pp_map_sim_k8(R, P, Q, M) pp_map_sim_oatep_k8(R, P, Q, M) + /** * Computes a multi-pairing of elliptic curve points defined on an elliptic * curve of embedding degree 12. Computes \prod e(P_i, Q_i). @@ -1520,6 +1541,17 @@ void pp_map_sim_weilp_k2(fp2_t r, const ep_t *p, const ep_t *q, int m); */ void pp_map_oatep_k8(fp8_t r, const ep_t p, const ep2_t q); +/** + * Computes the optimal ate multi-pairing in a parameterized elliptic + * curve with embedding degree 8. + * + * @param[out] r - the result. + * @param[in] q - the first pairing arguments. + * @param[in] p - the second pairing arguments. + * @param[in] m - the number of pairings to evaluate. + */ +void pp_map_sim_oatep_k8(fp8_t r, const ep_t *p, const ep2_t *q, int m); + /** * Computes the Tate pairing of two points in a parameterized elliptic curve * with embedding degree 12. diff --git a/include/relic_util.h b/include/relic_util.h index d24737bba..35763d41f 100644 --- a/include/relic_util.h +++ b/include/relic_util.h @@ -260,7 +260,7 @@ /*============================================================================*/ /** - * Toggle endianess of a digit. + * Toggle endianness of a digit. */ uint32_t util_conv_endian(uint32_t i); @@ -295,7 +295,7 @@ size_t util_bits_dig(dig_t a); * @param[in] n - the length in bytes of the buffers. * @return RLC_EQ if they are equal and RLC_NE otherwise. */ -int util_cmp_const(const void *a, const void *b, size_t n); +int util_cmp_sec(const void *a, const void *b, size_t n); /** * Computes a random permutation in [0, n-1]. diff --git a/preset/gmp-pbc-bls12-1150.sh b/preset/gmp-pbc-bls12-1150.sh new file mode 100755 index 000000000..4ed607e08 --- /dev/null +++ b/preset/gmp-pbc-bls12-1150.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cmake -DWSIZE=64 -DRAND=UDEV -DSHLIB=OFF -DSTBIN=ON -DTIMER=CYCLE -DCHECK=off -DVERBS=off -DARITH=gmp-sec -DBN_PRECI=1536 -DFP_PRIME=1150 -DFP_METHD="INTEG;INTEG;INTEG;MONTY;JMPDS;JMPDS;SLIDE" -DCFLAGS="-O3 -funroll-loops -fomit-frame-pointer -finline-small-functions -march=native -mtune=native" -DFP_PMERS=off -DFP_QNRES=off -DFPX_METHD="INTEG;INTEG;LAZYR" -DEP_PLAIN=off -DEP_SUPER=off -DPP_METHD="LAZYR;OATEP" $1 diff --git a/preset/gmp-pbc-k13072.sh b/preset/gmp-pbc-k13072.sh new file mode 100755 index 000000000..5eff63b76 --- /dev/null +++ b/preset/gmp-pbc-k13072.sh @@ -0,0 +1,2 @@ +#!/bin/sh +cmake -DCHECK=off -DARITH=gmp -DBN_PRECI=3072 -DFP_PRIME=3072 -DFP_QNRES=off -DFP_METHD="BASIC;COMBA;COMBA;MONTY;JMPDS;JMPDS;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" -DCFLAGS="-O2 -funroll-loops -fomit-frame-pointer" -DEP_PLAIN=on -DTESTS=10 -DBENCH=10 $1 diff --git a/preset/x64-pbc-afg16-765.sh b/preset/x64-pbc-fm16-765.sh similarity index 100% rename from preset/x64-pbc-afg16-765.sh rename to preset/x64-pbc-fm16-765.sh diff --git a/src/bn/relic_bn_mxp.c b/src/bn/relic_bn_mxp.c index b9080e609..625277f87 100644 --- a/src/bn/relic_bn_mxp.c +++ b/src/bn/relic_bn_mxp.c @@ -265,7 +265,7 @@ void bn_mxp_monty(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_grow(tab[1], m->alloc); for (i = bn_bits(b) - 1; i >= 0; i--) { j = bn_get_bit(b, i); - dv_swap_cond(tab[0]->dp, tab[1]->dp, m->alloc, j ^ 1); + dv_swap_sec(tab[0]->dp, tab[1]->dp, m->alloc, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; @@ -277,7 +277,7 @@ void bn_mxp_monty(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_mod(tab[0], tab[0], m, u); bn_sqr(tab[1], tab[1]); bn_mod(tab[1], tab[1], m, u); - dv_swap_cond(tab[0]->dp, tab[1]->dp, m->alloc, j ^ 1); + dv_swap_sec(tab[0]->dp, tab[1]->dp, m->alloc, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; diff --git a/src/cp/relic_cp_bls.c b/src/cp/relic_cp_bls.c index fac290e3e..6ddb347a9 100644 --- a/src/cp/relic_cp_bls.c +++ b/src/cp/relic_cp_bls.c @@ -66,7 +66,7 @@ int cp_bls_sig(g1_t s, const uint8_t *msg, size_t len, const bn_t d) { RLC_TRY { g1_new(p); g1_map(p, msg, len); - g1_mul_key(s, p, d); + g1_mul_sec(s, p, d); } RLC_CATCH_ANY { result = RLC_ERR; diff --git a/src/cp/relic_cp_ecdsa.c b/src/cp/relic_cp_ecdsa.c index 24657312d..34f0403dc 100644 --- a/src/cp/relic_cp_ecdsa.c +++ b/src/cp/relic_cp_ecdsa.c @@ -173,7 +173,7 @@ int cp_ecdsa_ver(const bn_t r, const bn_t s, const uint8_t *msg, size_t len, bn_mod(v, v, n); - cmp = dv_cmp_const(v->dp, r->dp, RLC_MIN(v->used, r->used)); + cmp = dv_cmp_sec(v->dp, r->dp, RLC_MIN(v->used, r->used)); result = (cmp == RLC_NE ? 0 : 1); if (v->used != r->used) { diff --git a/src/cp/relic_cp_ecies.c b/src/cp/relic_cp_ecies.c index da0a808f2..be64ac32d 100644 --- a/src/cp/relic_cp_ecies.c +++ b/src/cp/relic_cp_ecies.c @@ -138,7 +138,7 @@ int cp_ecies_dec(uint8_t *out, size_t *out_len, const ec_t r, const uint8_t *in, bn_write_bin(_x, l, x); md_kdf(key, 2 * size, _x, l); md_hmac(h, in, in_len - RLC_MD_LEN, key + size, size); - if (util_cmp_const(h, in + in_len - RLC_MD_LEN, RLC_MD_LEN)) { + if (util_cmp_sec(h, in + in_len - RLC_MD_LEN, RLC_MD_LEN)) { result = RLC_ERR; } else { if (bc_aes_cbc_dec(out, out_len, in, in_len - RLC_MD_LEN, diff --git a/src/cp/relic_cp_ecss.c b/src/cp/relic_cp_ecss.c index ac8c6cac8..7b1c1f776 100644 --- a/src/cp/relic_cp_ecss.c +++ b/src/cp/relic_cp_ecss.c @@ -166,7 +166,7 @@ int cp_ecss_ver(bn_t e, bn_t s, const uint8_t *msg, size_t len, const ec_t q) { bn_mod(ev, ev, n); - result = dv_cmp_const(ev->dp, e->dp, RLC_MIN(ev->used, + result = dv_cmp_sec(ev->dp, e->dp, RLC_MIN(ev->used, e->used)); result = (result == RLC_NE ? 0 : 1); diff --git a/src/cp/relic_cp_mklhs.c b/src/cp/relic_cp_mklhs.c index 96ef56890..2b070a716 100644 --- a/src/cp/relic_cp_mklhs.c +++ b/src/cp/relic_cp_mklhs.c @@ -88,7 +88,7 @@ int cp_mklhs_sig(g1_t s, const bn_t m, const char *data, const char *id, g1_map(a, str, strlen(id) + strlen(tag)); g1_add(s, s, a); g1_norm(s, s); - g1_mul_key(s, s, sk); + g1_mul_sec(s, s, sk); } RLC_CATCH_ANY { result = RLC_ERR; diff --git a/src/cp/relic_cp_rsa.c b/src/cp/relic_cp_rsa.c index c7ea1d67f..863f4d28e 100644 --- a/src/cp/relic_cp_rsa.c +++ b/src/cp/relic_cp_rsa.c @@ -938,7 +938,7 @@ int cp_rsa_ver(uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len, memset(h1, 0, RLC_MD_LEN); bn_write_bin(h1, size - pad_len, eb); /* Everything went ok, so signature status is changed. */ - result = util_cmp_const(h1, h2, RLC_MD_LEN); + result = util_cmp_sec(h1, h2, RLC_MD_LEN); } else { memcpy(h1 + 8, msg, msg_len); md_map(h2, h1, RLC_MD_LEN + 8); @@ -947,7 +947,7 @@ int cp_rsa_ver(uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len, bn_write_bin(h1, size - pad_len, eb); /* Everything went ok, so signature status is changed. */ - result = util_cmp_const(h1, h2, msg_len); + result = util_cmp_sec(h1, h2, msg_len); } #else memset(h1, 0, RLC_MAX(msg_len, RLC_MD_LEN)); @@ -956,10 +956,10 @@ int cp_rsa_ver(uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len, if (!hash) { md_map(h2, msg, msg_len); /* Everything went ok, so signature status is changed. */ - result = util_cmp_const(h1, h2, RLC_MD_LEN); + result = util_cmp_sec(h1, h2, RLC_MD_LEN); } else { /* Everything went ok, so signature status is changed. */ - result = util_cmp_const(h1, msg, msg_len); + result = util_cmp_sec(h1, msg, msg_len); } #endif result = (result == RLC_EQ ? 1 : 0); diff --git a/src/dv/relic_dv_util.c b/src/dv/relic_dv_util.c index 5084472a1..8422b636a 100644 --- a/src/dv/relic_dv_util.c +++ b/src/dv/relic_dv_util.c @@ -70,20 +70,20 @@ void dv_copy(dig_t *c, const dig_t *a, size_t digits) { memcpy(c, a, digits * sizeof(dig_t)); } -void dv_copy_cond(dig_t *c, const dig_t *a, size_t digits, dig_t cond) { +void dv_copy_sec(dig_t *c, const dig_t *a, size_t digits, dig_t bit) { dig_t mask, t; - mask = -cond; + mask = -bit; for (size_t i = 0; i < digits; i++) { t = (a[i] ^ c[i]) & mask; c[i] ^= t; } } -void dv_swap_cond(dig_t *c, dig_t *a, size_t digits, dig_t cond) { +void dv_swap_sec(dig_t *c, dig_t *a, size_t digits, dig_t bit) { dig_t mask, t; - mask = -cond; + mask = -bit; for (size_t i = 0; i < digits; i++) { t = (a[i] ^ c[i]) & mask; a[i] ^= t; @@ -106,7 +106,7 @@ int dv_cmp(const dig_t *a, const dig_t *b, size_t size) { return r; } -int dv_cmp_const(const dig_t *a, const dig_t *b, size_t size) { +int dv_cmp_sec(const dig_t *a, const dig_t *b, size_t size) { dig_t r = 0; for (size_t i = 0; i < size; i++) { diff --git a/src/eb/relic_eb_map.c b/src/eb/relic_eb_map.c index bbc61810f..2f87783ae 100644 --- a/src/eb/relic_eb_map.c +++ b/src/eb/relic_eb_map.c @@ -58,7 +58,7 @@ void eb_map(eb_t p, const uint8_t *msg, size_t len) { while (1) { dv_copy(p->x, k->dp, RLC_FB_DIGS); - eb_rhs(t1, p); + eb_rhs(t1, p->x); /* t0 = 1/x1^2. */ fb_sqr(t0, p->x); diff --git a/src/eb/relic_eb_mul.c b/src/eb/relic_eb_mul.c index b23b81141..eaef0d16c 100644 --- a/src/eb/relic_eb_mul.c +++ b/src/eb/relic_eb_mul.c @@ -712,7 +712,7 @@ void eb_mul_lodah(eb_t r, const eb_t p, const bn_t k) { bn_abs(t, k); bn_add(t, t, n); bn_add(n, t, n); - dv_swap_cond(t->dp, n->dp, RLC_MAX(t->used, n->used), + dv_swap_sec(t->dp, n->dp, RLC_MAX(t->used, n->used), bn_get_bit(t, bits) == 0); t->used = RLC_SEL(t->used, n->used, bn_get_bit(t, bits) == 0); @@ -743,8 +743,8 @@ void eb_mul_lodah(eb_t r, const eb_t p, const bn_t k) { fb_mul(r2, x2, z1); fb_add(r3, r1, r2); fb_muln_low(r4, r1, r2); - dv_swap_cond(x1, x2, RLC_FB_DIGS, j ^ 1); - dv_swap_cond(z1, z2, RLC_FB_DIGS, j ^ 1); + dv_swap_sec(x1, x2, RLC_FB_DIGS, j ^ 1); + dv_swap_sec(z1, z2, RLC_FB_DIGS, j ^ 1); fb_sqr(z1, r3); fb_muln_low(r1, z1, p->x); fb_addd_low(x1, r1, r4, 2 * RLC_FB_DIGS); @@ -775,8 +775,8 @@ void eb_mul_lodah(eb_t r, const eb_t p, const bn_t k) { fb_rdcn_low(x2, x2); break; } - dv_swap_cond(x1, x2, RLC_FB_DIGS, j ^ 1); - dv_swap_cond(z1, z2, RLC_FB_DIGS, j ^ 1); + dv_swap_sec(x1, x2, RLC_FB_DIGS, j ^ 1); + dv_swap_sec(z1, z2, RLC_FB_DIGS, j ^ 1); } if (fb_is_zero(z1)) { diff --git a/src/eb/relic_eb_pck.c b/src/eb/relic_eb_pck.c index 3766a2a2a..b012e47e3 100644 --- a/src/eb/relic_eb_pck.c +++ b/src/eb/relic_eb_pck.c @@ -63,7 +63,7 @@ int eb_upk(eb_t r, const eb_t p) { fb_new(t0); fb_new(t1); - eb_rhs(t1, p); + eb_rhs(t1, p->x); fb_sqr(t0, p->x); /* t0 = 1/x1^2. */ diff --git a/src/eb/relic_eb_util.c b/src/eb/relic_eb_util.c index fc44b7096..92316d739 100644 --- a/src/eb/relic_eb_util.c +++ b/src/eb/relic_eb_util.c @@ -78,7 +78,7 @@ void eb_rand(eb_t p) { } } -void eb_rhs(fb_t rhs, const eb_t p) { +void eb_rhs(fb_t rhs, const fb_t x) { fb_t t0, t1; fb_null(t0); @@ -89,9 +89,9 @@ void eb_rhs(fb_t rhs, const eb_t p) { fb_new(t1); /* t0 = x1^2. */ - fb_sqr(t0, p->x); + fb_sqr(t0, x); /* t1 = x1^3. */ - fb_mul(t1, t0, p->x); + fb_mul(t1, t0, x); /* t1 = x1^3 + a * x1^2 + b. */ switch (eb_curve_opt_a()) { @@ -171,7 +171,7 @@ int eb_on_curve(const eb_t p) { eb_norm(t, p); fb_mul(lhs, t->x, t->y); - eb_rhs(t->x, t); + eb_rhs(t->x, t->x); fb_sqr(t->y, t->y); fb_add(lhs, lhs, t->y); r = (fb_cmp(lhs, t->x) == RLC_EQ) || eb_is_infty(p); diff --git a/src/ed/relic_ed_map.c b/src/ed/relic_ed_map.c index e95f3da73..170e53387 100644 --- a/src/ed/relic_ed_map.c +++ b/src/ed/relic_ed_map.c @@ -97,7 +97,7 @@ void ed_map_ell2_5mod8(ed_t p, fp_t t) { fp_mul(p->x, p->x, p->z); { const int e1 = fp_cmp(p->x, tv4); - dv_copy_cond(p->y, tv2, RLC_FP_DIGS, e1 == RLC_EQ); + fp_copy_sec(p->y, tv2, e1 == RLC_EQ); } /* e1 goes out of scope */ /* compute numerator of g(x2) */ @@ -111,7 +111,7 @@ void ed_map_ell2_5mod8(ed_t p, fp_t t) { fp_mul(tv2, tv2, p->z); { const int e2 = fp_cmp(p->x, tv2); - dv_copy_cond(tv5, tv3, RLC_FP_DIGS, e2 == RLC_EQ); + fp_copy_sec(tv5, tv3, e2 == RLC_EQ); } /* e2 goes out of scope */ /* figure out whether we wanted y1 or y2 and x1 or x2 */ @@ -120,16 +120,16 @@ void ed_map_ell2_5mod8(ed_t p, fp_t t) { { const int e3 = fp_cmp(tv2, tv4); fp_set_dig(p->x, 1); - dv_copy_cond(p->x, tv1, RLC_FP_DIGS, e3 != RLC_EQ); + fp_copy_sec(p->x, tv1, e3 != RLC_EQ); fp_mul(p->x, p->x, c_486662); fp_neg(p->x, p->x); - dv_copy_cond(p->y, tv5, RLC_FP_DIGS, e3 != RLC_EQ); + fp_copy_sec(p->y, tv5, e3 != RLC_EQ); /* fix sign of y */ fp_prime_back(h, p->y); const int e4 = bn_get_bit(h, 0); fp_neg(tv2, p->y); - dv_copy_cond(p->y, tv2, RLC_FP_DIGS, (e3 == RLC_EQ) ^ (e4 == 1)); + fp_copy_sec(p->y, tv2, (e3 == RLC_EQ) ^ (e4 == 1)); } /* e3 and e4 go out of scope */ fp_add_dig(p->z, tv1, 1); @@ -147,9 +147,9 @@ void ed_map_ell2_5mod8(ed_t p, fp_t t) { /* exceptional case: either denominator == 0 */ const int e4 = fp_is_zero(p->z); fp_set_dig(tv5, 1); - dv_copy_cond(p->x, p->z, RLC_FP_DIGS, e4); /* set x to 0 */ - dv_copy_cond(p->y, tv5, RLC_FP_DIGS, e4); - dv_copy_cond(p->z, tv5, RLC_FP_DIGS, e4); + dv_copy_sec(p->x, p->z, RLC_FP_DIGS, e4); /* set x to 0 */ + dv_copy_sec(p->y, tv5, RLC_FP_DIGS, e4); + dv_copy_sec(p->z, tv5, RLC_FP_DIGS, e4); } /* e4 goes out of scope */ /* clear denominator / compute extended coordinates if necessary */ diff --git a/src/ed/relic_ed_mul.c b/src/ed/relic_ed_mul.c index 65f413a8e..0a9684b9f 100644 --- a/src/ed/relic_ed_mul.c +++ b/src/ed/relic_ed_mul.c @@ -149,35 +149,35 @@ static void ed_mul_reg_imp(ed_t r, const ed_t p, const bn_t k) { n = ((n ^ s) - s) >> 1; for (j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { - dv_copy_cond(u->x, t[j]->x, RLC_FP_DIGS, j == n); - dv_copy_cond(u->y, t[j]->y, RLC_FP_DIGS, j == n); - dv_copy_cond(u->z, t[j]->z, RLC_FP_DIGS, j == n); + fp_copy_sec(u->x, t[j]->x, j == n); + fp_copy_sec(u->y, t[j]->y, j == n); + fp_copy_sec(u->z, t[j]->z, j == n); #if ED_ADD == EXTND - dv_copy_cond(u->t, t[j]->t, RLC_FP_DIGS, j == n); + fp_copy_sec(u->t, t[j]->t, j == n); #endif } ed_neg(v, u); - dv_copy_cond(u->x, v->x, RLC_FP_DIGS, s != 0); + fp_copy_sec(u->x, v->x, s != 0); #if ED_ADD == EXTND - dv_copy_cond(u->t, v->t, RLC_FP_DIGS, s != 0); + fp_copy_sec(u->t, v->t, s != 0); #endif ed_add(r, r, u); } /* t[0] has an unmodified copy of p. */ ed_sub(u, r, t[0]); - dv_copy_cond(r->x, u->x, RLC_FP_DIGS, bn_is_even(k)); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, bn_is_even(k)); - dv_copy_cond(r->z, u->z, RLC_FP_DIGS, bn_is_even(k)); -#if ED_ADD == EXTND - dv_copy_cond(r->t, u->t, RLC_FP_DIGS, bn_is_even(k)); + fp_copy_sec(r->x, u->x, bn_is_even(k)); + fp_copy_sec(r->y, u->y, bn_is_even(k)); + fp_copy_sec(r->z, u->z, bn_is_even(k)); +#if ED_Afp == EXTND + fp_copy_sec(r->t, u->t, bn_is_even(k)); #endif /* Convert r to affine coordinates. */ ed_norm(r, r); ed_neg(u, r); - dv_copy_cond(r->x, u->x, RLC_FP_DIGS, bn_sign(k) == RLC_NEG); + fp_copy_sec(r->x, u->x, bn_sign(k) == RLC_NEG); #if ED_ADD == EXTND - dv_copy_cond(r->t, u->t, RLC_FP_DIGS, bn_sign(k) == RLC_NEG); + fp_copy_sec(r->t, u->t, bn_sign(k) == RLC_NEG); #endif } RLC_CATCH_ANY { @@ -342,19 +342,19 @@ void ed_mul_monty(ed_t r, const ed_t p, const bn_t k) { for (int i = bn_bits(k) - 1; i >= 0; i--) { int j = bn_get_bit(k, i); - dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND - dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif ed_add(t[0], t[0], t[1]); ed_dbl(t[1], t[1]); - dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND - dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif } diff --git a/src/ed/relic_ed_util.c b/src/ed/relic_ed_util.c index 8602a16bd..698780ac5 100644 --- a/src/ed/relic_ed_util.c +++ b/src/ed/relic_ed_util.c @@ -128,61 +128,46 @@ void ed_blind(ed_t r, const ed_t p) { } } -void ed_rhs(fp_t rhs, const ed_t p) { - fp_t t0, t1; - - fp_null(t0); - fp_null(t1); - - RLC_TRY { - fp_new(t0); - fp_new(t1); - - // 1 = a * X^2 + Y^2 - d * X^2 * Y^2 - fp_sqr(t0, p->x); - fp_mul(t0, t0, core_get()->ed_a); - fp_sqr(t1, p->y); - fp_add(t1, t1, t0); - fp_mul(t0, p->x, p->y); - fp_sqr(t0, t0); - fp_mul(t0, t0, core_get()->ed_d); - fp_sub(rhs, t1, t0); - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - fp_free(t0); - fp_free(t1); - } +void ed_rhs(fp_t rhs, const fp_t x) { + /* y^2 * (d * x^2 - 1) = 1a * x^2 - 1. */ + fp_sqr(rhs, x); + fp_mul(rhs, rhs, core_get()->ed_a); + fp_sub_dig(rhs, rhs, 1); } int ed_on_curve(const ed_t p) { ed_t t; - int r = 0; + int r = 1; ed_null(t); if (fp_is_zero(p->z)) { - r = 0; - } else { - RLC_TRY { - ed_new(t); - ed_norm(t, p); + return 0; + } + + RLC_TRY { + ed_new(t); + ed_norm(t, p); - ed_rhs(t->z, t); + /* Compute y^2 * (d * x^2 - 1) */ #if ED_ADD == EXTND - fp_mul(t->y, t->x, t->y); - r = ((fp_cmp_dig(t->z, 1) == RLC_EQ) && - (fp_cmp(t->y, t->t) == RLC_EQ)) || ed_is_infty(p); -#else - r = (fp_cmp_dig(t->z, 1) == RLC_EQ) || ed_is_infty(p); + fp_mul(t->z, t->x, t->y); + r &= (fp_cmp(t->z, t->t) == RLC_EQ); #endif - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - ed_free(t); - } + fp_sqr(t->z, t->y); + fp_sqr(t->t, t->x); + fp_mul(t->t, t->t, core_get()->ed_d); + fp_sub_dig(t->t, t->t, 1); + fp_mul(t->t, t->t, t->z); + ed_rhs(t->z, t->x); + r &= (fp_cmp(t->t, t->z) == RLC_EQ); + r |= ed_is_infty(p); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ed_free(t); } return r; } 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 80e3d0ae1..707a7cfdd 100644 --- a/src/ep/relic_ep_curve.c +++ b/src/ep/relic_ep_curve.c @@ -91,8 +91,6 @@ static void ep_curve_set_map(void) { dig_t *c2 = ctx->ep_map_c[2]; dig_t *c3 = ctx->ep_map_c[3]; dig_t *c4 = ctx->ep_map_c[4]; - dig_t *c5 = ctx->ep_map_c[5]; - dig_t *c6 = ctx->ep_map_c[6]; RLC_TRY { bn_new(t); @@ -173,42 +171,9 @@ static void ep_curve_set_map(void) { fp_mul_dig(c3, c3, 4); /* c3 *= 4 */ } - /* if b = 0, precompute constants. */ - if (ep_curve_opt_b() == RLC_ZERO) { - dig_t r = 0; - - fp_set_dig(c4, -fp_prime_get_qnr()); - fp_neg(c4, c4); - - bn_read_raw(t, fp_prime_get(), RLC_FP_DIGS); - bn_sub_dig(t, t, 1); - bn_rsh(t, t, 2); - fp_exp(c5, c4, t); - - bn_read_raw(t, fp_prime_get(), RLC_FP_DIGS); - if ((t->dp[0] & 0xF) == 5) { - /* n = (3p + 1)/16 */ - bn_mul_dig(t, t, 3); - bn_add_dig(t, t, 1); - r = 1; - } else { - /* n = (p + 3)/16 */ - bn_add_dig(t, t, 3); - r = 3; - } - bn_rsh(t, t, 4); - /* Compute d = 1/c^n. */ - fp_exp(c4, c4, t); - fp_inv(c4, c4); - fp_exp_dig(c5, c5, r); - /* Compute 1/sqrt(-1) as well. */ - fp_set_dig(c6, 1); - fp_neg(c6, c6); - fp_srt(c6, c6); - } - - /* If a = 0, precompute and store a square root of -3. */ - if (ep_curve_opt_a() == RLC_ZERO) { + /* If curve is not supersingular, precompute and store sqrt(-3) + * neeed for hashing using the SwiftEC algorithm and variants. */ + if (!ep_curve_is_super()) { fp_set_dig(c4, 3); fp_neg(c4, c4); if (!fp_srt(c4, c4)) { @@ -241,12 +206,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(); @@ -304,10 +266,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) { @@ -347,6 +305,9 @@ void ep_curve_mul_a(fp_t c, const fp_t a) { case RLC_ONE: fp_copy(c, a); break; + case RLC_TWO: + fp_dbl(c, a); + break; #if FP_RDC != MONTY case RLC_TINY: fp_mul_dig(c, a, ctx->ep_a[0]); @@ -378,26 +339,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; } @@ -580,3 +521,57 @@ void ep_curve_set_endom(const fp_t a, const fp_t b, const ep_t g, const bn_t r, } #endif + +int ep_curve_embed(void) { + switch (core_get()->ep_is_pairf) { + case EP_K1: + return 1; + case EP_SS2: + return 2; + case EP_GMT8: + return 8; + case EP_BN: + case EP_B12: + return 12; + case EP_N16: + case EP_FM16: + case EP_K16: + return 16; + case EP_K18: + case EP_FM18: + case EP_SG18: + return 18; + case EP_B24: + return 24; + case EP_B48: + return 48; + case EP_SG54: + return 54; + } + return 0; +} + +int ep_curve_frdim(void) { + size_t f = 0; + + switch (ep_curve_embed()) { + case 1: + case 2: + case 8: + return 1; + break; + case 12: + return 4; + break; + case 18: + return 6; + break; + case 16: + case 24: + return 8; + break; + case 48: + return 16; + break; + } +} \ No newline at end of file diff --git a/src/ep/relic_ep_dbl.c b/src/ep/relic_ep_dbl.c index 1a160d02c..f8548b6be 100644 --- a/src/ep/relic_ep_dbl.c +++ b/src/ep/relic_ep_dbl.c @@ -30,6 +30,7 @@ */ #include "relic_core.h" +#include "relic_ep_dbl_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -45,77 +46,7 @@ * @param[out] s - the slope. * @param[in] p - the point to double. */ -static void ep_dbl_basic_imp(ep_t r, fp_t s, const ep_t p) { - 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 = 1/2 * y1. */ - fp_dbl(t0, p->y); - fp_inv(t0, t0); - - /* t1 = 3 * x1^2 + a. */ - fp_sqr(t1, p->x); - fp_copy(t2, t1); - fp_dbl(t1, t1); - fp_add(t1, t1, t2); - - switch (ep_curve_opt_a()) { - case RLC_ZERO: - break; - case RLC_ONE: - fp_add_dig(t1, t1, (dig_t)1); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_add_dig(t1, t1, ep_curve_get_a()[0]); - break; -#endif - default: - fp_add(t1, t1, ep_curve_get_a()); - break; - } - - /* t1 = (3 * x1^2 + a)/(2 * y1). */ - fp_mul(t1, t1, t0); - - if (s != NULL) { - fp_copy(s, t1); - } - - /* t2 = t1^2. */ - fp_sqr(t2, t1); - - /* x3 = t1^2 - 2 * x1. */ - fp_dbl(t0, p->x); - fp_sub(t0, t2, t0); - - /* y3 = t1 * (x1 - x3) - y1. */ - fp_sub(t2, p->x, t0); - fp_mul(t1, t1, t2); - fp_sub(r->y, t1, p->y); - - fp_copy(r->x, t0); - fp_copy(r->z, p->z); - - r->coord = BASIC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp_free(t0); - fp_free(t1); - fp_free(t2); - } -} +TMPL_DBL_BASIC_IMP(ep, fp); #endif /* EP_ADD == BASIC */ @@ -128,144 +59,7 @@ static void ep_dbl_basic_imp(ep_t r, fp_t s, const ep_t p) { * @param r - the result. * @param p - the point to double. */ -static void ep_dbl_projc_imp(ep_t r, const ep_t p) { - 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 doubling from - * "Complete addition formulas for prime order elliptic curves" - * by Joost Renes, Craig Costello, and Lejla Batina - * https://eprint.iacr.org/2015/1060.pdf - */ - if (ep_curve_opt_a() == RLC_ZERO) { - /* Cost of 6M + 2S + 1m_3b + 9a. */ - fp_sqr(t0, p->y); - fp_mul(t3, p->x, p->y); - - if (p->coord == BASIC) { - /* Save 1M + 1S + 1m_b3 if z1 = 1. */ - fp_copy(t1, p->y); - fp_copy(t2, ep_curve_get_b3()); - } else { - fp_mul(t1, p->y, p->z); - fp_sqr(t2, p->z); - ep_curve_mul_b3(t2, t2); - } - fp_dbl(r->z, t0); - fp_dbl(r->z, r->z); - fp_dbl(r->z, r->z); - fp_mul(r->x, t2, r->z); - fp_add(r->y, t0, t2); - fp_mul(r->z, t1, r->z); - fp_dbl(t1, t2); - fp_add(t2, t1, t2); - fp_sub(t0, t0, t2); - fp_mul(r->y, t0, r->y); - fp_add(r->y, r->x, r->y); - fp_mul(r->x, t0, t3); - fp_dbl(r->x, r->x); - } else { - fp_sqr(t0, p->x); - fp_sqr(t1, p->y); - fp_mul(t3, p->x, p->y); - fp_dbl(t3, t3); - fp_mul(t4, p->y, p->z); - - if (ep_curve_opt_a() == RLC_MIN3) { - /* Cost of 8M + 3S + 2mb + 21a. */ - if (p->coord == BASIC) { - /* Save 1S + 1m_b + 2a if z1 = 1. */ - fp_set_dig(t2, 3); - fp_copy(r->y, ep_curve_get_b()); - } else { - fp_sqr(t2, p->z); - ep_curve_mul_b(r->y, t2); - fp_dbl(t5, t2); - fp_add(t2, t2, t5); - } - fp_mul(r->z, p->x, p->z); - fp_dbl(r->z, r->z); - fp_sub(r->y, r->y, r->z); - fp_dbl(r->x, r->y); - fp_add(r->y, r->x, r->y); - fp_sub(r->x, t1, r->y); - 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_b(r->z, r->z); - fp_sub(t3, r->z, t2); - fp_sub(t3, t3, t0); - fp_dbl(r->z, t3); - fp_add(t3, t3, r->z); - fp_dbl(r->z, t0); - fp_add(t0, t0, r->z); - fp_sub(t0, t0, t2); - } else { - /* 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_copy(t2, ep_curve_get_a()); - } else { - fp_sqr(t2, p->z); - ep_curve_mul_b3(r->y, t2); - ep_curve_mul_a(t2, t2); - } - fp_mul(r->z, p->x, p->z); - fp_dbl(r->z, r->z); - ep_curve_mul_a(r->x, r->z); - fp_add(r->y, r->x, r->y); - fp_sub(r->x, t1, r->y); - 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_sub(t3, t0, t2); - ep_curve_mul_a(t3, t3); - fp_add(t3, t3, r->z); - fp_dbl(r->z, t0); - fp_add(t0, t0, r->z); - fp_add(t0, t0, t2); - } - /* Common part with renamed variables. */ - fp_mul(t0, t0, t3); - fp_add(r->y, r->y, t0); - fp_dbl(t2, t4); - fp_mul(t0, t2, t3); - fp_sub(r->x, r->x, t0); - fp_mul(r->z, t2, t1); - fp_dbl(r->z, r->z); - fp_dbl(r->z, r->z); - } - - 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_DBL_PROJC_IMP(ep, fp); #endif /* EP_ADD == PROJC */ @@ -278,205 +72,7 @@ static void ep_dbl_projc_imp(ep_t r, const ep_t p) { * @param r - the result. * @param p - the point to double. */ -static void ep_dbl_jacob_imp(ep_t r, const ep_t p) { - fp_t t0, t1, t2, t3, t4, t5; - - 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); - - if (p->coord != BASIC && ep_curve_opt_a() == RLC_MIN3) { - /* dbl-2001-b formulas: 3M + 5S + 8add + 1*4 + 2*8 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b */ - - /* t0 = delta = z1^2. */ - fp_sqr(t0, p->z); - - /* t1 = gamma = y1^2. */ - fp_sqr(t1, p->y); - - /* t2 = beta = x1 * y1^2. */ - fp_mul(t2, p->x, t1); - - /* t3 = alpha = 3 * (x1 - z1^2) * (x1 + z1^2). */ - fp_sub(t3, p->x, t0); - fp_add(t4, p->x, t0); - fp_mul(t4, t3, t4); - fp_dbl(t3, t4); - fp_add(t3, t3, t4); - - /* x3 = alpha^2 - 8 * beta. */ - fp_dbl(t2, t2); - fp_dbl(t2, t2); - fp_dbl(t5, t2); - fp_sqr(r->x, t3); - fp_sub(r->x, r->x, t5); - - /* z3 = (y1 + z1)^2 - gamma - delta. */ - fp_add(r->z, p->y, p->z); - fp_sqr(r->z, r->z); - fp_sub(r->z, r->z, t1); - fp_sub(r->z, r->z, t0); - - /* y3 = alpha * (4 * beta - x3) - 8 * gamma^2. */ - fp_dbl(t1, t1); - fp_sqr(t1, t1); - fp_dbl(t1, t1); - fp_sub(r->y, t2, r->x); - fp_mul(r->y, r->y, t3); - fp_sub(r->y, r->y, t1); - } else if (ep_curve_opt_a() == RLC_ZERO) { - /* dbl-2009-l formulas: 2M + 5S + 6add + 1*8 + 3*2 + 1*3. */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l */ - - /* A = X1^2 */ - fp_sqr(t0, p->x); - - /* B = Y1^2 */ - fp_sqr(t1, p->y); - - /* C = B^2 */ - fp_sqr(t2, t1); - - /* D = 2*((X1+B)^2-A-C) */ - fp_add(t1, t1, p->x); - fp_sqr(t1, t1); - fp_sub(t1, t1, t0); - fp_sub(t1, t1, t2); - fp_dbl(t1, t1); - - /* E = 3*A */ - fp_dbl(t3, t0); - fp_add(t0, t3, t0); - - /* F = E^2 */ - fp_sqr(t3, t0); - - /* Z3 = 2*Y1*Z1 */ - fp_mul(r->z, p->y, p->z); - fp_dbl(r->z, r->z); - - /* X3 = F-2*D */ - fp_sub(r->x, t3, t1); - fp_sub(r->x, r->x, t1); - - /* Y3 = E*(D-X3)-8*C */ - fp_sub(r->y, t1, r->x); - fp_mul(r->y, r->y, t0); - fp_dbl(t2, t2); - fp_dbl(t2, t2); - fp_dbl(t2, t2); - fp_sub(r->y, r->y, t2); - } else { - /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ - - /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ - fp_sqr(t0, p->x); - fp_sqr(t1, p->y); - fp_sqr(t2, t1); - - if (p->coord != BASIC) { - /* t3 = z1^2. */ - fp_sqr(t3, p->z); - - if (ep_curve_opt_a() == RLC_ZERO) { - /* z3 = 2 * y1 * z1. */ - fp_mul(r->z, p->y, p->z); - fp_dbl(r->z, r->z); - } else { - /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ - fp_add(r->z, p->y, p->z); - fp_sqr(r->z, r->z); - fp_sub(r->z, r->z, t1); - fp_sub(r->z, r->z, t3); - } - } else { - /* z3 = 2 * y1. */ - fp_dbl(r->z, p->y); - } - - /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ - fp_add(t4, p->x, t1); - fp_sqr(t4, t4); - fp_sub(t4, t4, t0); - fp_sub(t4, t4, t2); - fp_dbl(t4, t4); - - /* t5 = M = 3 * x1^2 + a * z1^4. */ - fp_dbl(t5, t0); - fp_add(t5, t5, t0); - if (p->coord != BASIC) { - fp_sqr(t3, t3); - switch (ep_curve_opt_a()) { - case RLC_ZERO: - break; - case RLC_ONE: - fp_add(t5, t5, t3); - break; - case RLC_TINY: - fp_mul_dig(t1, t3, ep_curve_get_a()[0]); - fp_add(t5, t5, t1); - break; - default: - fp_mul(t1, t3, ep_curve_get_a()); - fp_add(t5, t5, t1); - break; - } - } else { - switch (ep_curve_opt_a()) { - case RLC_ZERO: - break; - case RLC_ONE: - fp_add_dig(t5, t5, (dig_t)1); - break; - case RLC_TINY: - fp_add_dig(t5, t5, ep_curve_get_a()[0]); - break; - default: - fp_add(t5, t5, ep_curve_get_a()); - break; - } - } - - /* x3 = T = M^2 - 2 * S. */ - fp_sqr(r->x, t5); - fp_dbl(t1, t4); - fp_sub(r->x, r->x, t1); - - /* y3 = M * (S - T) - 8 * y1^4. */ - fp_dbl(t2, t2); - fp_dbl(t2, t2); - fp_dbl(t2, t2); - fp_sub(t4, t4, r->x); - fp_mul(t5, t5, t4); - fp_sub(r->y, t5, t2); - } - - 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); - } -} +TMPL_DBL_JACOB_IMP(ep, fp); #endif /* EP_ADD == JACOB */ diff --git a/src/ep/relic_ep_map.c b/src/ep/relic_ep_map.c index 714efdf5b..4b7841b7a 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 */ @@ -57,20 +57,19 @@ TMPL_MAP_ISOGENY_MAP(ep, fp, iso); #endif /* EP_CTMAP */ -#define EP_MAP_COPY_COND(O, I, C) dv_copy_cond(O, I, RLC_FP_DIGS, C) /** * Simplified SWU mapping from Section 4 of * "Fast and simple constant-time hashing to the BLS12-381 Elliptic Curve" */ -TMPL_MAP_SSWU(ep, fp, dig_t, EP_MAP_COPY_COND); +TMPL_MAP_SSWU(ep, fp, dig_t); /** * Shallue--van de Woestijne map, based on the definition from * draft-irtf-cfrg-hash-to-curve-06, Section 6.6.1 */ -TMPL_MAP_SVDW(ep, fp, dig_t, EP_MAP_COPY_COND); +TMPL_MAP_SVDW(ep, fp, dig_t); -#undef EP_MAP_COPY_COND +#undef EP_MAP_copy_sec /** * Maps an array of uniformly random bytes to a point in a prime elliptic @@ -120,7 +119,7 @@ static void ep_map_from_field(ep_t p, const uint8_t *uniform_bytes, size_t len, /* compare sign of y and sign of t; fix if necessary */ \ neg = neg != fp_is_even(PT->y); \ fp_neg(t, PT->y); \ - dv_copy_cond(PT->y, t, RLC_FP_DIGS, neg); \ + dv_copy_sec(PT->y, t, RLC_FP_DIGS, neg); \ } while (0) /* first map invocation */ @@ -180,7 +179,7 @@ void ep_map_basic(ep_t p, const uint8_t *msg, size_t len) { fp_set_dig(p->z, 1); while (1) { - ep_rhs(t0, p); + ep_rhs(t0, p->x); if (fp_smb(t0) == 1) { fp_srt(p->y, t0); @@ -240,14 +239,29 @@ 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 a, b, c, t, u, v, w, y, x1, y1, z1; + fp_t a, b, c, d, e, f, t, u, v, w, y, x1, y1, z1, den[3]; ctx_t *ctx = core_get(); bn_t k; + if (ep_curve_is_super()) { + RLC_FREE(pseudo_random_bytes); + RLC_THROW(ERR_NO_CONFIG); + return; + } + + if (ctx->mod18 % 3 == 2) { + RLC_FREE(pseudo_random_bytes); + RLC_THROW(ERR_NO_CONFIG); + return; + } + bn_null(k); fp_null(a); fp_null(b); fp_null(c); + fp_null(d); + fp_null(e); + fp_null(f); fp_null(t); fp_null(u); fp_null(v); @@ -256,12 +270,18 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) { fp_null(x1); fp_null(y1); fp_null(z1); + fp_null(den[0]); + fp_null(den[1]); + fp_null(den[2]); RLC_TRY { bn_new(k); fp_new(a); fp_new(b); fp_new(c); + fp_new(d); + fp_new(e); + fp_new(f); fp_new(t); fp_new(u); fp_new(v); @@ -270,6 +290,9 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) { fp_new(x1); fp_new(y1); fp_new(z1); + fp_new(den[0]); + fp_new(den[1]); + fp_new(den[2]); md_xmd(pseudo_random_bytes, 2 * len_per_elm + 1, msg, len, (const uint8_t *)"RELIC", 5); @@ -280,298 +303,137 @@ 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) { + fp_sqr(a, u); + fp_sqr(b, a); + fp_mul(c, b, a); + if (ep_curve_opt_a() == RLC_ONE) { + fp_add_dig(c, c, 64); + } else { + fp_dbl(f, ep_curve_get_a()); + fp_dbl(f, f); + fp_sqr(e, f); + fp_mul(e, e, f); + fp_add(c, c, e); + } + fp_sqr(d, t); - 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 */ - 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); + fp_mul(v, a, d); + fp_mul(v, v, u); + fp_mul_dig(v, v, 24); + fp_mul(v, v, ctx->ep_map_c[4]); - /* Compute x^2, x^4 and x^6 in sequence. */ - fp_sqr(z1, u); - fp_sqr(y1, z1); - fp_mul(t, z1, y1); + fp_sub_dig(p->x, ctx->ep_map_c[4], 1); + fp_hlv(p->x, p->x); - 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_sqr(w, b); + fp_mul(y, v, a); + if (ep_curve_opt_a() == RLC_ONE) { 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 */ - fp_set_dig(c, -fp_prime_get_qnr()); - fp_neg(c, c); - - /* u = t0, t = t1, v = t0^4, y = t1^4, w = c^2, z1 = 8*a^2*c. */ - fp_sqr(v, u); - fp_sqr(v, v); - fp_sqr(y, t); - fp_sqr(y, y); - fp_sqr(w, c); - fp_sqr(z1, a); - fp_mul(z1, z1, c); - fp_dbl(z1, z1); - fp_dbl(z1, z1); - fp_dbl(z1, z1); - /* w = c^2*t0^4+t1^4, y1 = c^4*t0^8, x1 = 2*c^2*t0^4*t1^4, y = t1^8. */ - fp_mul(w, w, v); - fp_sqr(y1, w); - fp_mul(x1, w, y); - fp_dbl(x1, x1); - fp_add(w, w, y); - fp_sqr(y, y); - /* w = den = 8*a^2*c(c^2*t0^4 + t1^4), z1 = 16*a^3*c^2. */ - fp_mul(w, w, z1); - fp_inv(p->z, w); - fp_mul(z1, z1, c); - fp_mul(z1, z1, a); - fp_dbl(z1, z1); - /* v = num2 = c^4*t0^8 - 2*c^2t0^4*t1^4 + t1^8 - 16*a^3*c^2*/ - fp_sub(v, y1, x1); - fp_add(v, v, y); - fp_sub(v, v, z1); - /* w = num0 = t0 * ac(-3*c^4t0^8 + 2c^2*t0^4*t1^4 + t1^8 + 16*a^3*c^2)*/ - fp_add(w, y, z1); - fp_add(w, w, x1); - fp_sub(w, w, y1); - fp_sub(w, w, y1); - fp_sub(w, w, y1); - fp_mul(w, w, u); - fp_mul(w, w, c); - fp_mul(w, w, a); - /* z1 = num1 = t1 * ac^2(c^4t0^8 + 2c^2t0^4*t1^4 - 3^t1^8 + 16a^3c^2)*/ - fp_sub(z1, z1, y); - fp_sub(z1, z1, y); - fp_sub(z1, z1, y); - fp_add(z1, z1, x1); - fp_add(z1, z1, y1); - fp_mul(z1, z1, t); - fp_mul(z1, z1, c); - fp_mul(z1, z1, c); - fp_mul(z1, z1, a); - /* v2 = num2/den = v/w. */ - fp_mul(w, w, p->z); - fp_mul(z1, z1, p->z); - fp_mul(v, v, p->z); - fp_inv(v, v); - - bn_read_raw(k, fp_prime_get(), RLC_FP_DIGS); - if ((k->dp[0] & 0xF) == 5) { - /* n = (3p + 1)/16 */ - bn_mul_dig(k, k, 3); - bn_add_dig(k, k, 1); - } else if ((k->dp[0] & 0xF) == 13) { - /* n = (p + 3)/16 */ - bn_add_dig(k, k, 3); } else { - RLC_THROW(ERR_NO_VALID); + fp_mul(t, f, c); } - bn_rsh(k, k, 4); - /* Compute x1 = f = (1/v2)^3 + a*(1/v2) = (1/v2)((1/v2)^2 + a). */ - fp_sqr(x1, v); - fp_add(x1, x1, a); - fp_mul(x1, x1, v); - /* Compute y = theta, zp = theta^4. */ - fp_exp(y, x1, k); - fp_sqr(p->z, y); - fp_sqr(p->z, p->z); - /* Perform the base change from (t0,t1) to (u0, u1). */ - fp_sqr(u, u); - fp_mul(u, u, c); - fp_sqr(t, t); - fp_mul(t, t, c); - /* Compute c = i^r * f. */ - fp_mul(c, ctx->ep_map_c[5], x1); - fp_sqr(p->y, y); - /* We use zp as temporary, but there is no problem with \psi. */ - int index = 0; - fp_copy(y1, u); - fp_copy(a, v); - fp_sqr(b, y); - fp_copy(p->x, a); - fp_copy(p->y, b); - for (int m = 0; m < 4; m++) { - fp_mul(y1, y1, ctx->ep_map_c[5]); - index += (fp_bits(y1) < fp_bits(u)); + fp_add(y, y, t); + fp_mul(y, y, p->x); + + fp_add(den[0], c, v); + fp_mul(den[0], den[0], u); + fp_mul(den[0], den[0], ctx->ep_map_c[4]); + fp_mul(den[0], den[0], p->x); + fp_dbl(den[0], den[0]); + fp_neg(den[0], den[0]); + fp_mul(den[1], den[0], p->x); + if (ep_curve_opt_a() == RLC_ONE) { + fp_sub_dig(den[2], a, 4); + } else { + fp_sub(den[2], a, f); } - /* Apply consecutive endomorphisms. */ - for (int m = 0; m < 4; m++) { - fp_neg(a, a); - fp_mul(b, b, ep_curve_get_beta()); - dv_copy_cond(p->x, a, RLC_FP_DIGS, m < index); - dv_copy_cond(p->y, b, RLC_FP_DIGS, m < index); + fp_sqr(den[2], den[2]); + fp_mul_dig(den[2], den[2], 216); + fp_dbl(den[2], den[2]); + fp_neg(den[2], den[2]); + fp_mul(den[2], den[2], b); + fp_mul(den[2], den[2], d); + + if (fp_is_zero(den[0]) || fp_is_zero(den[1]) || fp_is_zero(den[2])) { + ep_set_infty(p); + } else { + fp_inv_sim(den, den, 3); + if (ep_curve_opt_a() == RLC_ONE) { + fp_dbl(a, a); + fp_dbl(a, a); + fp_dbl(a, a); + fp_dbl(a, a); + fp_add(y1, a, v); + fp_dbl(y1, y1); + fp_dbl(y1, y1); + } else { + fp_mul(y1, f, v); + fp_mul(u, a, e); + fp_add(y1, y1, u); + } + fp_add(y1, y1, w); + fp_mul(z1, y, p->x); + fp_add(x1, y1, z1); + fp_add(y1, y1, y); + + if (ep_curve_opt_a() == RLC_ONE) { + fp_dbl(e, b); + fp_dbl(e, e); + fp_add(z1, a, e); + } else { + fp_mul(z1, f, a); + fp_add(z1, z1, b); + fp_mul(z1, z1, f); + } + fp_dbl(t, z1); + fp_add(z1, z1, t); + fp_sub(z1, c, z1); + fp_sub(z1, z1, v); + fp_mul(z1, z1, v); + if (ep_curve_opt_a() == RLC_ONE) { + fp_dbl(a, a); + fp_dbl(a, a); + fp_dbl(a, a); + fp_set_dig(d, 64); + fp_sqr(d, d); + } else { + fp_dbl(a, u); + fp_sqr(d, e); + } + fp_add(a, a, w); + fp_mul(u, a, b); + fp_sub(z1, u, z1); + fp_add(z1, z1, d); + + fp_mul(x1, x1, den[0]); + fp_mul(y1, y1, den[1]); + fp_mul(z1, z1, den[2]); + + ep_rhs(t, x1); + ep_rhs(u, y1); + ep_rhs(v, z1); + + int c2 = fp_is_sqr(u); + int c3 = fp_is_sqr(v); + + fp_copy_sec(t, u, c2); + fp_copy_sec(x1, y1, c2); + fp_copy_sec(t, v, c3); + fp_copy_sec(x1, z1, c3); + + if (!fp_srt(t, t)) { + RLC_THROW(ERR_NO_VALID); + } + fp_neg(u, t); + fp_copy_sec(t, u, fp_is_even(t) ^ s); + + fp_copy(p->x, x1); + fp_copy(p->y, t); + fp_set_dig(p->z, 1); + p->coord = BASIC; } - fp_neg(y1, x1); - /* Compute 1/d * 1/theta. */ - fp_inv(y, y); - fp_mul(y, y, ctx->ep_map_c[4]); - dig_t c0 = fp_cmp(p->z, x1) == RLC_EQ; - dig_t c1 = fp_cmp(p->z, y1) == RLC_EQ; - dig_t c2 = fp_cmp(p->z, c) == RLC_EQ; - fp_neg(c, c); - dig_t c3 = fp_cmp(p->z, c) == RLC_EQ; - c2 = !c0 && !c1 && c2; - c3 = !c0 && !c1 && !c2 && c3; - fp_copy(p->z, ctx->ep_map_c[6]); - fp_mul(p->z, p->z, p->y); - dv_copy_cond(p->y, p->z, RLC_FP_DIGS, c1); - fp_copy(y1, ctx->ep_map_c[4]); - /* Convert from projective coordinates on the surface to affine. */ - fp_mul(u, u, v); - fp_mul(t, t, v); - fp_sqr(v, v); - fp_mul(w, w, v); - fp_mul(z1, z1, v); - /* Compute (x,y) = (x0/(d*theta)^2, y0/(d*theta)^3). */ - fp_sqr(y1, y); - fp_mul(u, u, y1); - fp_mul(w, w, y); - fp_mul(w, w, y1); - dv_copy_cond(p->x, u, RLC_FP_DIGS, c2); - dv_copy_cond(p->y, w, RLC_FP_DIGS, c2); - /* Compute (x,y) = (x1/(d^3*theta)^2, y1/(d^3*theta)^3). */ - fp_mul(z1, z1, y); - fp_mul(t, t, y1); - fp_mul(z1, z1, y1); - fp_sqr(y, ctx->ep_map_c[4]); - fp_mul(z1, z1, y); - fp_sqr(y, y); - fp_mul(t, t, y); - 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); - p->coord = BASIC; - fp_set_dig(p->z, 1); } else { /* This is the SwiftEC case per se. */ if (ep_curve_opt_a() != RLC_ZERO) { @@ -623,16 +485,16 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) { int c2 = fp_is_sqr(u); int c3 = fp_is_sqr(v); - dv_swap_cond(x1, y1, RLC_FP_DIGS, c2); - dv_swap_cond(t, u, RLC_FP_DIGS, c2); - dv_swap_cond(x1, z1, RLC_FP_DIGS, c3); - dv_swap_cond(t, v, RLC_FP_DIGS, c3); + fp_copy_sec(x1, y1, c2); + fp_copy_sec(t, u, c2); + fp_copy_sec(x1, z1, c3); + fp_copy_sec(t, v, c3); if (!fp_srt(t, t)) { RLC_THROW(ERR_NO_VALID); } fp_neg(u, t); - dv_swap_cond(t, u, RLC_FP_DIGS, fp_is_even(t) ^ s); + fp_copy_sec(t, u, fp_is_even(t) ^ s); fp_copy(p->x, x1); fp_copy(p->y, t); @@ -652,6 +514,9 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) { fp_free(a); fp_free(b); fp_free(c); + fp_free(d); + fp_free(e); + fp_free(f); fp_free(t); fp_free(u); fp_free(v); @@ -660,6 +525,9 @@ void ep_map_swift(ep_t p, const uint8_t *msg, size_t len) { fp_free(x1); fp_free(y1); fp_free(z1); + fp_free(den[0]); + fp_free(den[1]); + fp_free(den[2]); RLC_FREE(pseudo_random_bytes); } } diff --git a/src/ep/relic_ep_mul.c b/src/ep/relic_ep_mul.c index db0fda139..c79cf404d 100644 --- a/src/ep/relic_ep_mul.c +++ b/src/ep/relic_ep_mul.c @@ -208,39 +208,35 @@ static void ep_mul_naf_imp(ep_t r, const ep_t p, const bn_t k) { #endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_MUL == LWNAF */ +#if EP_MUL == LWREG || !defined(STRIP) #if defined(EP_ENDOM) static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { - int i, j, n0, n1, s0, s1, b0, b1; - int8_t _s0, _s1, reg0[RLC_FP_BITS + 1], reg1[RLC_FP_BITS + 1]; - bn_t n, _k, k0, k1, v1[3], v2[3]; - ep_t q, t[1 << (RLC_WIDTH - 2)], u, v, w; + int8_t reg[2][RLC_FP_BITS + 1], s[2], b[2], c0, c1, n0, n1; + bn_t n, _k[2], v1[3], v2[3]; + ep_t q, t[1 << (RLC_WIDTH - 2)], u, w; size_t l; bn_null(n); - bn_null(_k); - bn_null(k0); - bn_null(k1); + bn_null(_k[0]); + bn_null(_k[1]); ep_null(q); ep_null(u); - ep_null(v); ep_null(w); RLC_TRY { bn_new(n); - bn_new(_k); - bn_new(k0); - bn_new(k1); + bn_new(_k[0]); + bn_new(_k[1]); ep_new(q); ep_new(u); - ep_new(v); ep_new(w); - for (i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { ep_null(t[i]); ep_new(t[i]); } - for (i = 0; i < 3; i++) { + for (size_t i = 0; i < 3; i++) { bn_null(v1[i]); bn_null(v2[i]); bn_new(v1[i]); @@ -251,27 +247,25 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { ep_curve_get_v1(v1); ep_curve_get_v2(v2); - bn_mod(_k, k, n); + bn_mod(_k[0], k, n); - bn_rec_glv(k0, k1, _k, n, (const bn_t *)v1, (const bn_t *)v2); - s0 = bn_sign(k0); - s1 = bn_sign(k1); - bn_abs(k0, k0); - bn_abs(k1, k1); - b0 = bn_is_even(k0); - b1 = bn_is_even(k1); - k0->dp[0] |= b0; - k1->dp[0] |= b1; - - ep_copy(q, p); - ep_neg(t[0], p); - dv_copy_cond(q->y, t[0]->y, RLC_FP_DIGS, s0 != RLC_POS); + bn_rec_glv(_k[0], _k[1], _k[0], n, (const bn_t *)v1, (const bn_t *)v2); + for (size_t i = 0; i < 2; i++) { + s[i] = bn_sign(_k[i]); + bn_abs(_k[i], _k[i]); + b[i] = bn_is_even(_k[i]); + _k[i]->dp[0] |= b[i]; + } + + ep_norm(t[0], p); + ep_neg(q, t[0]); + dv_copy_sec(q->y, t[0]->y, RLC_FP_DIGS, s[0] == RLC_POS); ep_tab(t, q, RLC_WIDTH); l = RLC_FP_BITS + 1; - bn_rec_reg(reg0, &l, k0, bn_bits(n)/2, RLC_WIDTH); + bn_rec_reg(reg[0], &l, _k[0], bn_bits(n) >> 1, RLC_WIDTH); l = RLC_FP_BITS + 1; - bn_rec_reg(reg1, &l, k1, bn_bits(n)/2, RLC_WIDTH); + bn_rec_reg(reg[1], &l, _k[1], bn_bits(n) >> 1, RLC_WIDTH); #if defined(EP_MIXED) fp_set_dig(u->z, 1); @@ -281,53 +275,51 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { u->coord = w->coord = EP_ADD; #endif ep_set_infty(r); - for (i = l - 1; i >= 0; i--) { - for (j = 0; j < RLC_WIDTH - 1; j++) { + for (int i = l - 1; i >= 0; i--) { + for (size_t j = 0; j < RLC_WIDTH - 1; j++) { ep_dbl(r, r); } - n0 = reg0[i]; - _s0 = (n0 >> 7); - n0 = ((n0 ^ _s0) - _s0) >> 1; - n1 = reg1[i]; - _s1 = (n1 >> 7); - n1 = ((n1 ^ _s1) - _s1) >> 1; - - for (j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { - dv_copy_cond(u->x, t[j]->x, RLC_FP_DIGS, j == n0); - dv_copy_cond(w->x, t[j]->x, RLC_FP_DIGS, j == n1); - dv_copy_cond(u->y, t[j]->y, RLC_FP_DIGS, j == n0); - dv_copy_cond(w->y, t[j]->y, RLC_FP_DIGS, j == n1); -#if !defined(EP_MIXED) - dv_copy_cond(u->z, t[j]->z, RLC_FP_DIGS, j == n0); - dv_copy_cond(w->z, t[j]->z, RLC_FP_DIGS, j == n1); + n0 = reg[0][i]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + n1 = reg[1][i]; + c1 = (n1 >> 7); + n1 = ((n1 ^ c1) - c1) >> 1; + + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + fp_copy_sec(u->x, t[j]->x, j == n0); + fp_copy_sec(w->x, t[j]->x, j == n1); + fp_copy_sec(u->y, t[j]->y, j == n0); + fp_copy_sec(w->y, t[j]->y, j == n1); +#if !defined(EP_fpXED) + fp_copy_sec(u->z, t[j]->z, j == n0); + fp_copy_sec(w->z, t[j]->z, j == n1); #endif } - ep_neg(v, u); - dv_copy_cond(u->y, v->y, RLC_FP_DIGS, _s0 != 0); - ep_add(r, r, u); + ep_neg(q, u); + fp_copy_sec(q->y, u->y, c0 == 0); + ep_add(r, r, q); ep_psi(w, w); ep_neg(q, w); - dv_copy_cond(w->y, q->y, RLC_FP_DIGS, s0 != s1); - ep_neg(q, w); - dv_copy_cond(w->y, q->y, RLC_FP_DIGS, _s1 != 0); + fp_copy_sec(w->y, q->y, (c1 != 0) ^ (s[0] != s[1])); ep_add(r, r, w); } /* t[0] has an unmodified copy of p. */ ep_sub(u, r, t[0]); - dv_copy_cond(r->x, u->x, RLC_FP_DIGS, b0); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, b0); - dv_copy_cond(r->z, u->z, RLC_FP_DIGS, b0); + fp_copy_sec(r->x, u->x, b[0]); + fp_copy_sec(r->y, u->y, b[0]); + fp_copy_sec(r->z, u->z, b[0]); ep_psi(w, t[0]); ep_neg(q, w); - dv_copy_cond(w->y, q->y, RLC_FP_DIGS, s0 != s1); - ep_sub(u, r, w); - dv_copy_cond(r->x, u->x, RLC_FP_DIGS, b1); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, b1); - dv_copy_cond(r->z, u->z, RLC_FP_DIGS, b1); + fp_copy_sec(q->y, w->y, s[0] == s[1]); + ep_sub(u, r, q); + fp_copy_sec(r->x, u->x, b[1]); + fp_copy_sec(r->y, u->y, b[1]); + fp_copy_sec(r->z, u->z, b[1]); /* Convert r to affine coordinates. */ ep_norm(r, r); @@ -337,18 +329,16 @@ static void ep_mul_reg_glv(ep_t r, const ep_t p, const bn_t k) { } RLC_FINALLY { bn_free(n); - bn_free(_k); - bn_free(k0); - bn_free(k1); + bn_free(_k[0]); + bn_free(_k[1]); bn_free(n); ep_free(q); ep_free(u); - ep_free(v); ep_free(w); - for (i = 0; i < 1 << (RLC_WIDTH - 2); i++) { + for (size_t i = 0; i < 1 << (RLC_WIDTH - 2); i++) { ep_free(t[i]); } - for (i = 0; i < 3; i++) { + for (size_t i = 0; i < 3; i++) { bn_free(v1[i]); bn_free(v2[i]); } @@ -408,25 +398,25 @@ static void ep_mul_reg_imp(ep_t r, const ep_t p, const bn_t k) { n = ((n ^ s) - s) >> 1; for (j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { - dv_copy_cond(u->x, t[j]->x, RLC_FP_DIGS, j == n); - dv_copy_cond(u->y, t[j]->y, RLC_FP_DIGS, j == n); + fp_copy_sec(u->x, t[j]->x, j == n); + fp_copy_sec(u->y, t[j]->y, j == n); #if !defined(EP_MIXED) - dv_copy_cond(u->z, t[j]->z, RLC_FP_DIGS, j == n); + fp_copy_sec(u->z, t[j]->z, j == n); #endif } ep_neg(v, u); - dv_copy_cond(u->y, v->y, RLC_FP_DIGS, s != 0); + fp_copy_sec(u->y, v->y, s != 0); ep_add(r, r, u); } /* t[0] has an unmodified copy of p. */ ep_sub(u, r, t[0]); - dv_copy_cond(r->x, u->x, RLC_FP_DIGS, bn_is_even(k)); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, bn_is_even(k)); - dv_copy_cond(r->z, u->z, RLC_FP_DIGS, bn_is_even(k)); + fp_copy_sec(r->x, u->x, bn_is_even(k)); + fp_copy_sec(r->y, u->y, bn_is_even(k)); + fp_copy_sec(r->z, u->z, bn_is_even(k)); /* Convert r to affine coordinates. */ ep_norm(r, r); ep_neg(u, r); - dv_copy_cond(r->y, u->y, RLC_FP_DIGS, bn_sign(k) == RLC_NEG); + fp_copy_sec(r->y, u->y, bn_sign(k) == RLC_NEG); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -443,6 +433,7 @@ static void ep_mul_reg_imp(ep_t r, const ep_t p, const bn_t k) { } #endif /* EP_PLAIN || EP_SUPER */ +#endif /* EP_MUL == LWREG */ /*============================================================================*/ /* Public definitions */ @@ -612,7 +603,7 @@ void ep_mul_monty(ep_t r, const ep_t p, const bn_t k) { bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); - dv_swap_cond(l->dp, n->dp, RLC_MAX(l->used, n->used), + dv_swap_sec(l->dp, n->dp, RLC_MAX(l->used, n->used), bn_get_bit(l, bits) == 0); l->used = RLC_SEL(l->used, n->used, bn_get_bit(l, bits) == 0); @@ -625,14 +616,14 @@ void ep_mul_monty(ep_t r, const ep_t p, const bn_t k) { for (int i = bits - 1; i >= 0; i--) { int j = bn_get_bit(l, i); - dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); ep_add(t[0], t[0], t[1]); ep_dbl(t[1], t[1]); - dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); } ep_norm(r, t[0]); diff --git a/src/ep/relic_ep_mul_cof.c b/src/ep/relic_ep_mul_cof.c index e80b3b861..2101f6ece 100644 --- a/src/ep/relic_ep_mul_cof.c +++ b/src/ep/relic_ep_mul_cof.c @@ -149,7 +149,7 @@ void ep_mul_cof(ep_t r, const ep_t p) { default: /* multiply by cofactor to get the correct group. */ ep_curve_get_cof(k); - ep_mul_basic(r, p, k); + ep_mul_big(r, p, k); } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/ep/relic_ep_param.c b/src/ep/relic_ep_param.c index 81e10d48c..c2b9a25ed 100644 --- a/src/ep/relic_ep_param.c +++ b/src/ep/relic_ep_param.c @@ -660,18 +660,6 @@ #endif #if defined(EP_ENDOM) && FP_PRIME == 765 -/** - * Parameters for a 765-bit pairing-friendly prime curve. - */ -/** @{ */ -#define N16_P765_A "1" -#define N16_P765_B "0" -#define N16_P765_X "71A955588AD4E8236811AA1770428A86CA487504E3964600E51FAD83E8EDF03883360471538D685B7CA156BC9AD56E6FED4BE76C099A752E70E867A8FD79CDFBD0C00294E59C4F2F348302FB270336BE8D2EC25E6234D33CB33C8840BC059D4" -#define N16_P765_Y "F6DEB4CAA67257010A3286CECBE4E4127D53701CF5897E3426F675BEFE36F60CD0E779433306B0A34C826584307F96100ECA6EB01F69637C2EB0B295E6C13E9721A5EA0FC05A04B47FC565AEBF41016525A69F554BC9D68D9EF2B5CD77D1D4" -#define N16_P765_R "9965D956A0DBC8AF273C0100000000000000000000000000000000000000000000000000000000000000000000000001" -#define N16_P765_H "26597655A836F22BC9CF003FFFFFFFFFFFFFA30FAB330D5A7F0000000000000000000000384F01000000000000000000" -/** @} */ - /** * Parameters for a 765-bit pairing-friendly prime curve. */ @@ -704,10 +692,10 @@ /** @{ */ #define N16_P766_A "1" #define N16_P766_B "0" -#define N16_P766_X "09B60388917DF4F526CE1869B8A069F7722A4EABF0543BAE29B7CABACC1BE50626878F5CC3C5157ADCC6B80DE516239BE3CCC8E66173CBD91092C87B1AAEBF072F3C92CC5B6A8F33A6A2A165AC171A76C4687274BA0E54A7C049F0781D6EB3F5" -#define N16_P766_Y "280BAA585CD0AB9090B8AB2990410AA093511C661554ACC497D77B67BE3B3CCDDFBCBE296A0119EF8F8FA19D613CA25D16232EF4A5A019C6FDD4C2F0F8DBC238C84F07326BACB3D0478AB5596DCC8BCAD483BF2C4AD89A6C29683E85E77DF120" -#define N16_P766_R "FFFFFF8401001A46937D417AB554F4F3438C3F42C66CBA08998426591ED55EBA6A16CB364728D491BC20010000000001" -#define N16_P766_H "3FFFFFE100400691A4DF505EAD553D3CD0E38FD0B1746ED22B12363612FBBA252C222C274D60ADA6C3F09E1010080100" +#define N16_P766_X "177E5E088795AE368F68ADB4938F647BCCB7D0BCB70456E3B3BC0C6EE12FA3D0E1DFC2FD81C215EC25E602DE8BCEE98A7F8FC23E4A296B9DDEF34BB90A27DD4804B90F7783FE2C891A820941DB16535E1FD73E73038A520AAE396F0949D7E46D" +#define N16_P766_Y "1CE39931AB952C962CBF6F4E8BE79D6AD3D931B2B100185707032C109C9476305F44D30E1D551E965D44D661327D878EC47ED7A9D1DCDDCA96091E74FB4FF6D42CE809579AB9C72417C55849377E4BA31A0B5F687D840E4CE99E63D583050147" +#define N16_P766_R "FFFF7000238FFAF4807374994CF93FE6E28D406881B18D350193FE6E3E533E4073749FEBD2000238FFFFDC0000010001" +#define N16_P766_H "3FFFDC0008E3FEBD201CDD26533E4FF9B8A3D019F36C69AB3FF0479FDCFCBD856CEE5D9B2D34778FD7D2F6D2DC004204" /** @} */ #endif @@ -726,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. @@ -1176,11 +1178,6 @@ void ep_param_set(int param) { break; #endif #if defined(EP_ENDOM) && FP_PRIME == 765 - case N16_P765: - ASSIGN(N16_P765, N16_765); - endom = 1; - pairf = EP_N16; - break; case FM16_P765: ASSIGN(FM16_P765, FM16_765); endom = 1; @@ -1206,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); @@ -1482,13 +1486,14 @@ int ep_param_set_any_endom(void) { //ep_param_set(SG18_P638); #endif #elif FP_PRIME == 765 - ep_param_set(N16_P765); - //ep_param_set(FM16_P765); + ep_param_set(FM16_P765); #elif FP_PRIME == 766 //ep_param_set(K16_P766); 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 @@ -1603,8 +1608,7 @@ int ep_param_set_any_pairf(void) { extension = 3; #endif #elif FP_PRIME == 765 - ep_param_set(N16_P765); - //ep_param_set(FM16_P765); + ep_param_set(FM16_P765); type = RLC_EP_MTYPE; extension = 4; #elif FP_PRIME == 766 @@ -1616,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; @@ -1765,8 +1773,8 @@ void ep_param_print(void) { case SG18_P638: util_banner("Curve SG18-P638:", 0); break; - case N16_P765: - util_banner("Curve N16-P765:", 0); + case N16_P766: + util_banner("Curve N16-P766:", 0); break; case FM16_P765: util_banner("Curve FM16-P765:", 0); @@ -1777,6 +1785,9 @@ void ep_param_print(void) { case FM18_P768: util_banner("Curve FM18-P768:", 0); break; + case B12_P1150: + util_banner("Curve B12-P1150:", 0); + break; case SS_P1536: util_banner("Curve SS-P1536:", 0); break; @@ -1836,7 +1847,7 @@ int ep_param_level(void) { case B12_P455: return 140; case NIST_P384: - case N16_P765: + case B12_P1150: case FM16_P765: case K16_P766: case FM18_P768: @@ -1852,32 +1863,3 @@ int ep_param_level(void) { } return 0; } - -int ep_param_embed(void) { - switch (core_get()->ep_is_pairf) { - case EP_K1: - return 1; - case EP_SS2: - return 2; - case EP_GMT8: - return 8; - case EP_BN: - case EP_B12: - return 12; - case EP_N16: - case EP_FM16: - case EP_K16: - return 16; - case EP_K18: - case EP_FM18: - case EP_SG18: - return 18; - case EP_B24: - return 24; - case EP_B48: - return 48; - case EP_SG54: - return 54; - } - return 0; -} diff --git a/src/ep/relic_ep_pck.c b/src/ep/relic_ep_pck.c index 2aac19239..54f3859b1 100644 --- a/src/ep/relic_ep_pck.c +++ b/src/ep/relic_ep_pck.c @@ -89,7 +89,7 @@ int ep_upk(ep_t r, const ep_t p) { bn_new(halfQ); bn_new(yValue); - ep_rhs(t, p); + ep_rhs(t, p->x); /* t0 = sqrt(x1^3 + a * x1 + b). */ result = fp_srt(t, t); diff --git a/src/ep/relic_ep_util.c b/src/ep/relic_ep_util.c index 0229fa228..a39269949 100644 --- a/src/ep/relic_ep_util.c +++ b/src/ep/relic_ep_util.c @@ -107,7 +107,7 @@ void ep_blind(ep_t r, const ep_t p) { } } -void ep_rhs(fp_t rhs, const ep_t p) { +void ep_rhs(fp_t rhs, const fp_t x) { fp_t t0; fp_null(t0); @@ -116,7 +116,7 @@ void ep_rhs(fp_t rhs, const ep_t p) { fp_new(t0); /* t0 = x1^2. */ - fp_sqr(t0, p->x); + fp_sqr(t0, x); /* t0 = x1^2 + a */ switch (ep_curve_opt_a()) { @@ -142,7 +142,7 @@ void ep_rhs(fp_t rhs, const ep_t p) { } /* t0 = x1^3 + a * x */ - fp_mul(t0, t0, p->x); + fp_mul(t0, t0, x); /* t0 = x1^3 + a * x + b */ switch (ep_curve_opt_b()) { @@ -185,7 +185,7 @@ int ep_on_curve(const ep_t p) { ep_new(t); ep_norm(t, p); - ep_rhs(t->x, t); + ep_rhs(t->x, t->x); fp_sqr(t->y, t->y); r = (fp_cmp(t->x, t->y) == RLC_EQ) || ep_is_infty(p); } RLC_CATCH_ANY { diff --git a/src/epx/relic_ep2_add.c b/src/epx/relic_ep2_add.c index 2e4f563dc..599e73373 100644 --- a/src/epx/relic_ep2_add.c +++ b/src/epx/relic_ep2_add.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of addition on prime elliptic curves over quadratic - * extensions. + * Implementation of addition on prime elliptic curves over a quadratic + * extension field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,312 +43,62 @@ * 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 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 */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) -#if defined(EP_MIXED) || !defined(STRIP) +/** + * Adds a point represented in homogeneous coordinates to a point represented in + * 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. + */ +TMPL_ADD_PROJC_MIX(ep2, fp2); /** - * Adds a point represented in affine coordinates to a point represented in - * projective coordinates. + * Adds two points represented in homogeneous coordinates on an ordinary prime + * elliptic curve. * - * @param r - the result. - * @param s - the slope. - * @param p - the affine point. - * @param q - the projective point. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep2_add_projc_mix(ep2_t r, const ep2_t p, const ep2_t q) { - fp2_t t0, t1, t2, t3, t4, t5, t6; +TMPL_ADD_PROJC_IMP(ep2, fp2); - fp2_null(t0); - fp2_null(t1); - fp2_null(t2); - fp2_null(t3); - fp2_null(t4); - fp2_null(t5); - fp2_null(t6); +#endif /* EP_ADD == PROJC */ - RLC_TRY { - fp2_new(t0); - fp2_new(t1); - fp2_new(t2); - fp2_new(t3); - fp2_new(t4); - fp2_new(t5); - fp2_new(t6); - - if (p->coord != BASIC) { - /* t0 = z1^2. */ - fp2_sqr(t0, p->z); - - /* t3 = U2 = x2 * z1^2. */ - fp2_mul(t3, q->x, t0); - - /* t1 = S2 = y2 * z1^3. */ - fp2_mul(t1, t0, p->z); - fp2_mul(t1, t1, q->y); - - /* t3 = H = U2 - x1. */ - fp2_sub(t3, t3, p->x); - - /* t1 = R = 2 * (S2 - y1). */ - fp2_sub(t1, t1, p->y); - } else { - /* H = x2 - x1. */ - fp2_sub(t3, q->x, p->x); - - /* t1 = R = 2 * (y2 - y1). */ - fp2_sub(t1, q->y, p->y); - } - - /* t2 = HH = H^2. */ - fp2_sqr(t2, t3); - - /* If E is zero. */ - if (fp2_is_zero(t3)) { - if (fp2_is_zero(t1)) { - /* If I is zero, p = q, should have doubled. */ - ep2_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep2_set_infty(r); - } - } else { - /* t5 = J = H * HH. */ - fp2_mul(t5, t3, t2); - - /* t4 = V = x1 * HH. */ - fp2_mul(t4, p->x, t2); - - /* x3 = R^2 - J - 2 * V. */ - fp2_sqr(r->x, t1); - fp2_sub(r->x, r->x, t5); - fp2_dbl(t6, t4); - fp2_sub(r->x, r->x, t6); - - /* y3 = R * (V - x3) - Y1 * J. */ - fp2_sub(t4, t4, r->x); - fp2_mul(t4, t4, t1); - fp2_mul(t1, p->y, t5); - fp2_sub(r->y, t4, t1); - - if (p->coord != BASIC) { - /* z3 = z1 * H. */ - fp2_mul(r->z, p->z, t3); - } else { - /* z3 = H. */ - fp2_copy(r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); - fp2_free(t2); - fp2_free(t3); - fp2_free(t4); - fp2_free(t5); - fp2_free(t6); - } -} +#if EP_ADD == JACOB || !defined(STRIP) -#endif +/** + * Adds a point represented in Jacobian coordinates to a point represented in + * 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. + */ +TMPL_ADD_JACOB_MIX(ep2, fp2); /** - * Adds two points represented in projective coordinates on an ordinary prime + * Adds two points represented in Jacobian coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep2_add_projc_imp(ep2_t r, const ep2_t p, const ep2_t q) { -#if defined(EP_MIXED) && defined(STRIP) - ep2_add_projc_mix(r, p, q); -#else /* General addition. */ - fp2_t t0, t1, t2, t3, t4, t5, t6; - - fp2_null(t0); - fp2_null(t1); - fp2_null(t2); - fp2_null(t3); - fp2_null(t4); - fp2_null(t5); - fp2_null(t6); +TMPL_ADD_JACOB_IMP(ep2, fp2); - RLC_TRY { - fp2_new(t0); - fp2_new(t1); - fp2_new(t2); - fp2_new(t3); - fp2_new(t4); - fp2_new(t5); - fp2_new(t6); - - if (q->coord == BASIC) { - ep2_add_projc_mix(r, p, q); - } else { - /* t0 = z1^2. */ - fp2_sqr(t0, p->z); - - /* t1 = z2^2. */ - fp2_sqr(t1, q->z); - - /* t2 = U1 = x1 * z2^2. */ - fp2_mul(t2, p->x, t1); - - /* t3 = U2 = x2 * z1^2. */ - fp2_mul(t3, q->x, t0); - - /* t6 = z1^2 + z2^2. */ - fp2_add(t6, t0, t1); - - /* t0 = S2 = y2 * z1^3. */ - fp2_mul(t0, t0, p->z); - fp2_mul(t0, t0, q->y); - - /* t1 = S1 = y1 * z2^3. */ - fp2_mul(t1, t1, q->z); - fp2_mul(t1, t1, p->y); - - /* t3 = H = U2 - U1. */ - fp2_sub(t3, t3, t2); - - /* t0 = R = 2 * (S2 - S1). */ - fp2_sub(t0, t0, t1); - - fp2_dbl(t0, t0); - - /* If E is zero. */ - if (fp2_is_zero(t3)) { - if (fp2_is_zero(t0)) { - /* If I is zero, p = q, should have doubled. */ - ep2_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep2_set_infty(r); - } - } else { - /* t4 = I = (2*H)^2. */ - fp2_dbl(t4, t3); - fp2_sqr(t4, t4); - - /* t5 = J = H * I. */ - fp2_mul(t5, t3, t4); - - /* t4 = V = U1 * I. */ - fp2_mul(t4, t2, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp2_sqr(r->x, t0); - fp2_sub(r->x, r->x, t5); - fp2_dbl(t2, t4); - fp2_sub(r->x, r->x, t2); - - /* y3 = R * (V - x3) - 2 * S1 * J. */ - fp2_sub(t4, t4, r->x); - fp2_mul(t4, t4, t0); - fp2_mul(t1, t1, t5); - fp2_dbl(t1, t1); - fp2_sub(r->y, t4, t1); - - /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ - fp2_add(r->z, p->z, q->z); - fp2_sqr(r->z, r->z); - fp2_sub(r->z, r->z, t6); - fp2_mul(r->z, r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); - fp2_free(t2); - fp2_free(t3); - fp2_free(t4); - fp2_free(t5); - fp2_free(t6); - } -#endif -} - -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ /* Public definitions */ @@ -385,7 +136,7 @@ void ep2_add_slp_basic(ep2_t r, fp2_t s, const ep2_t p, const ep2_t q) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep2_add_projc(ep2_t r, const ep2_t p, const ep2_t q) { if (ep2_is_infty(p)) { @@ -398,13 +149,25 @@ void ep2_add_projc(ep2_t r, const ep2_t p, const ep2_t q) { return; } - if (p == q) { - /* TODO: This is a quick hack. Should we fix this? */ - ep2_dbl(r, p); + ep2_add_projc_imp(r, p, q); +} + +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep2_add_jacob(ep2_t r, const ep2_t p, const ep2_t q) { + if (ep2_is_infty(p)) { + ep2_copy(r, q); return; } - ep2_add_projc_imp(r, p, q); + if (ep2_is_infty(q)) { + ep2_copy(r, p); + return; + } + + ep2_add_jacob_imp(r, p, q); } #endif @@ -421,7 +184,6 @@ void ep2_sub(ep2_t r, const ep2_t p, const ep2_t q) { RLC_TRY { ep2_new(t); - ep2_neg(t, q); ep2_add(r, p, t); } diff --git a/src/epx/relic_ep2_cmp.c b/src/epx/relic_ep2_cmp.c index 8c44a9eba..1b265c6ab 100644 --- a/src/epx/relic_ep2_cmp.c +++ b/src/epx/relic_ep2_cmp.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of utilities for prime elliptic curves over quadratic - * extensions. + * Implementation of utilities for prime elliptic curves over a quadratic + * extension field. * * @ingroup epx */ @@ -37,46 +37,69 @@ /*============================================================================*/ int ep2_cmp(const ep2_t p, const ep2_t q) { - ep2_t r, s; - int result = RLC_NE; + ep2_t r, s; + int result = RLC_NE; if (ep2_is_infty(p) && ep2_is_infty(q)) { return RLC_EQ; } - ep2_null(r); - ep2_null(s); + ep2_null(r); + ep2_null(s); - RLC_TRY { - ep2_new(r); - ep2_new(s); + RLC_TRY { + ep2_new(r); + ep2_new(s); - if ((p->coord != BASIC) && (q->coord != BASIC)) { - /* If the two points are not normalized, it is faster to compare - * x1 * z2^2 == x2 * z1^2 and y1 * z2^3 == y2 * z1^3. */ - fp2_sqr(r->z, p->z); - fp2_sqr(s->z, q->z); - fp2_mul(r->x, p->x, s->z); - fp2_mul(s->x, q->x, r->z); - fp2_mul(r->z, r->z, p->z); - fp2_mul(s->z, s->z, q->z); - fp2_mul(r->y, p->y, s->z); - fp2_mul(s->y, q->y, r->z); - } else { - ep2_norm(r, p); - ep2_norm(s, q); - } + switch (q->coord) { + case PROJC: + /* If q is in homogeneous projective coordinates, compute + * x1 * z2 and y1 * z2. */ + fp2_mul(r->x, p->x, q->z); + fp2_mul(r->y, p->y, q->z); + break; + case JACOB: + /* If q is in Jacobian projective coordinates, compute + * x2 * z1^2 and y2 * z1^3. */ + fp2_sqr(r->z, q->z); + fp2_mul(r->x, p->x, r->z); + fp2_mul(r->z, r->z, q->z); + fp2_mul(r->y, p->y, r->z); + break; + default: + ep2_copy(r, p); + break; + } - if ((fp2_cmp(r->x, s->x) == RLC_EQ) && + switch (p->coord) { + /* Now do the same for the other point. */ + case PROJC: + fp2_mul(s->x, q->x, p->z); + fp2_mul(s->y, q->y, p->z); + break; + case JACOB: + fp2_sqr(s->z, p->z); + fp2_mul(s->x, q->x, s->z); + fp2_mul(s->z, s->z, p->z); + fp2_mul(s->y, q->y, s->z); + break; + default: + ep2_copy(s, q); + break; + } + + if ((fp2_cmp(r->x, s->x) == RLC_EQ) && (fp2_cmp(r->y, s->y) == RLC_EQ)) { - result = RLC_EQ; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - ep2_free(r); - ep2_free(s); - } + result = RLC_EQ; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep2_free(r); + ep2_free(s); + } - return result; + return result; } diff --git a/src/epx/relic_ep2_curve.c b/src/epx/relic_ep2_curve.c index 3ec781ba0..99ccdb978 100644 --- a/src/epx/relic_ep2_curve.c +++ b/src/epx/relic_ep2_curve.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of configuration of prime elliptic curves over quadratic - * extensions. + * Implementation of configuration of prime elliptic curves over a quadratic + * extension field. * * @ingroup epx */ @@ -53,8 +53,8 @@ #define BN_P158_Y1 "074866EA7BD0AB4C67C77F70E0467F1FF32D800D" #define BN_P158_R "240000006ED000007FE96000419F59800C9FFD81" #define BN_P158_H "240000006ED000007FEA200041A07F800CA06E0D" -#define BN_P158_MAPU0 "0" -#define BN_P158_MAPU1 "-1" +#define BN_P158_MAPU0 "0" +#define BN_P158_MAPU1 "-1" /** @} */ #endif @@ -70,8 +70,8 @@ #define BN_P254_Y1 "0EBB2B0E7C8B15268F6D4456F5F38D37B09006FFD739C9578A2D1AEC6B3ACE9B" #define BN_P254_R "2523648240000001BA344D8000000007FF9F800000000010A10000000000000D" #define BN_P254_H "2523648240000001BA344D8000000008C2A2800000000016AD00000000000019" -#define BN_P254_MAPU0 "0" -#define BN_P254_MAPU1 "-1" +#define BN_P254_MAPU0 "0" +#define BN_P254_MAPU1 "-1" /** @} */ #endif @@ -87,8 +87,8 @@ #define BN_P256_Y1 "A033144CA161E3E3271624B3F0CC1CE607ACD2CBCE9E9253C732CF3E1016DEE7" #define BN_P256_R "B64000000000FF2F2200000085FD547FD8001F44B6B7F4B7C2BC818F7B6BEF99" #define BN_P256_H "B64000000000FF2F2200000085FD548188001F44B6B9232AC2BC818FB05BDDC5" -#define BN_P256_MAPU0 "0" -#define BN_P256_MAPU1 "-1" +#define BN_P256_MAPU0 "0" +#define BN_P256_MAPU1 "-1" /** @} */ #endif @@ -104,8 +104,8 @@ #define SM9_P256_Y1 "17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96" #define SM9_P256_R "B640000002A3A6F1D603AB4FF58EC74449F2934B18EA8BEEE56EE19CD69ECF25" #define SM9_P256_H "B640000002A3A6F1D603AB4FF58EC745F9F2934B1C0B51C8E57054B2F003BBD5" -#define SM9_P256_MAPU0 "-1" -#define SM9_P256_MAPU1 "0" +#define SM9_P256_MAPU0 "-1" +#define SM9_P256_MAPU1 "0" /** @} */ #endif @@ -168,8 +168,8 @@ #define BN_P382_Y1 "09CAC2932F3C894CCE129ECBB49AFD4BFF94C10B5DF37AB469E3455F16EFDD304721F689BFF864A92ACB3F4DF52678ED" #define BN_P382_R "24009015183F94892D996CC179C6D1666F82CEFBE47879BB46E4CDA2E2E2281D08DC008E80108252004200000000000D" #define BN_P382_H "24009015183F94892D996CC179C6D1666F82CEFBE47879BC06E64DD9A31E2BEF09B400A08016832A005A000000000019" -#define BN_P382_MAPU0 "0" -#define BN_P382_MAPU1 "-1" +#define BN_P382_MAPU0 "0" +#define BN_P382_MAPU1 "-1" /** @} */ #endif @@ -185,8 +185,8 @@ #define B12_P383_Y1 "1459B073246773B35CBCBFC9318AC47DDC1C284887D1DA4BE13593ACC0E45B748AF4115011A3EA730A7DB21A83562411" #define B12_P383_R "1002001800C00B809C04401C81698B381DE05F095A120D3973B2099EBFEBC0001" #define B12_P383_H "1C78E45562AB68EE641721902ED56C9B45EB1276A5C15CB19C7BF81F7A7B6F22053BAC3422240A3F4A7E3C25D470E7BABDB8A2E1E1793BF9CEBDD1BF2EFE30E5" -#define B12_P383_MAPU0 "0" -#define B12_P383_MAPU1 "1" +#define B12_P383_MAPU0 "0" +#define B12_P383_MAPU1 "1" /** @} */ #endif @@ -202,8 +202,8 @@ #define BN_P446_Y1 "91F93BEB46071DEDF410DC5A7662DD8B4BBC8BE5D3A8662009A4C2C0577F82A2337D208379F21C65F90FE1D90482CC48DEC83BFB8AD8E45" #define BN_P446_R "2400000000000000002400000002D00000000D800000021C00000017A0000000870000000AD400000054C000000156000000126000000061" #define BN_P446_H "2400000000000000002400000002D00000000D800000021C0000001860000000870000000B340000005AC00000016200000013E00000006D" -#define BN_P446_MAPU0 "0" -#define BN_P446_MAPU1 "1" +#define BN_P446_MAPU0 "0" +#define BN_P446_MAPU1 "1" /** @} */ #endif @@ -219,8 +219,8 @@ #define B12_P446_Y1 "10ACDEBE52C1499796809283C38E100C4BA9FA0699696BF9F8647CB18EE632A4DDDAA771A78C031F868FAFA07E8642CCA633FE6F99B744C4" #define B12_P446_R "511B70539F27995B34995830FA4D04C98CCC4C050BC7BB9B0E8D8CA34610428001400040001" #define B12_P446_H "2DAEE3988A06F1BB3444D5780484639BF731D657742BF556901567CEFE5C3DD2555CB74C3560CED298D5147F8E24B79369C54C81E026DD55B51D6A75088593E6A92EFCE555594000638E5" -#define B12_P446_MAPU0 "0" -#define B12_P446_MAPU1 "1" +#define B12_P446_MAPU0 "0" +#define B12_P446_MAPU1 "1" /** @} */ #endif @@ -236,21 +236,21 @@ #define B12_P455_Y1 "24AC244C6F31FDAC1214CA62AB4DB7BA9B5F0D54D56A3D5C680044225C3AAF9815C272A15AA1D28FB6AC9EB7B0BE6916450794A617AFFB4EF9" #define B12_P455_R "10000080000380002E0000F10004F00025E000750001D1000A00000400001C00007FFFFC00001" #define B12_P455_H "1C71C8E38E4C71C8238726432AFAC33B9D05A24A43A2531F1F9DE9B4C688A0B7A2716C48868F7C7D716F8AB8D45A1B9B21F9EB90E83876E4E18AD09613EC7DCAF8B8E238558711C838C718E5" -#define B12_P455_MAPU0 "0" -#define B12_P455_MAPU1 "1" +#define B12_P455_MAPU0 "0" +#define B12_P455_MAPU1 "1" /** @} */ #endif #if defined(EP_ENDOM) && FP_PRIME == 544 /** @{ */ -#define GMT8_P544_A0 "0" -#define GMT8_P544_A1 "2" -#define GMT8_P544_B0 "0" -#define GMT8_P544_B1 "0" -#define GMT8_P544_X0 "1EE84A939A46EAE4287805E2FFABBCED3605B74F5FD7E545F390D2E3D34AD0C60851EA65A18CF92396B9318FCAB3205D79C8D03E928590F719E4086A1C42AF2D40EB6C3A" -#define GMT8_P544_X1 "065F721D63381C07D1BF556D65A3A82B0E969BA031FB3812F49709926D5159324DFB685048D4EAFC914F893A0D5382868D1D252619AA964149258DCC1A86B68775F36A82" -#define GMT8_P544_Y0 "9B80046683050F459F48D7CE4C83992D5B044718326AEE2DD86F3E5557BD240441A763BC40030F21FC3A64483B450330930BAFA62E7B573B565404A9DB2A5BFF7D6994D4" -#define GMT8_P544_Y1 "AB457A64E140799D3D9B77ECEA828957F3AEADB3278FEE32E9AD77F068DD2F95B469607E8CE3CE5705276F869CFB18270C0A8FC8D8AD0D17545F4DCCC9E599853A7BAB76" +#define GMT8_P544_A0 "0" +#define GMT8_P544_A1 "2" +#define GMT8_P544_B0 "0" +#define GMT8_P544_B1 "0" +#define GMT8_P544_X0 "1EE84A939A46EAE4287805E2FFABBCED3605B74F5FD7E545F390D2E3D34AD0C60851EA65A18CF92396B9318FCAB3205D79C8D03E928590F719E4086A1C42AF2D40EB6C3A" +#define GMT8_P544_X1 "065F721D63381C07D1BF556D65A3A82B0E969BA031FB3812F49709926D5159324DFB685048D4EAFC914F893A0D5382868D1D252619AA964149258DCC1A86B68775F36A82" +#define GMT8_P544_Y0 "9B80046683050F459F48D7CE4C83992D5B044718326AEE2DD86F3E5557BD240441A763BC40030F21FC3A64483B450330930BAFA62E7B573B565404A9DB2A5BFF7D6994D4" +#define GMT8_P544_Y1 "AB457A64E140799D3D9B77ECEA828957F3AEADB3278FEE32E9AD77F068DD2F95B469607E8CE3CE5705276F869CFB18270C0A8FC8D8AD0D17545F4DCCC9E599853A7BAB76" #define GMT8_P544_R "FF0060739E18D7594A978B0AB6AE4CE3DBFD52A9D00197603FFFDF0000000101" #define GMT8_P544_H "8A0A079FC7C3D421A4986FAAA10A6593F60BC94E32AEE8067E35551B86D59F0F61BD6A750917746236DD39CB4710BD44B7BE86F0A8E5324DFE802973060F04BF37C018705B78072182D139A8D2BD338A630511676FDAFD47C60DB5393F9DFC96089B1FFB60B78FB2" #define GMT8_P544_MAPU0 "0" @@ -270,8 +270,8 @@ #define BN_P638_Y1 "1A650343ACEF6895FE4EC59B49F40E043DEB05DEF170DFD71B44CAB9496E2EADD034EC0E9238544556902D2D51AB93D224DC757AD720F4DE8ED3BFA4E22DB0ECE92369F681543F23A908A9B319D5FAEF" #define BN_P638_R "23FFFFFDC000000D7FFFFFB8000001D3FFFFF942D000165E3FFF94870000D52FFFFDD0E00008DE55600086550021E555FFFFF54FFFF4EAC000000049800154D9FFFFFFFFFFFFEDA00000000000000061" #define BN_P638_H "23FFFFFDC000000D7FFFFFB8000001D3FFFFF942D000165E3FFF94870000D52FFFFDD0E00008DE562000864F0021E561FFFFF4EFFFF4EC400000004F800160C1FFFFFFFFFFFFEC20000000000000006D" -#define BN_P638_MAPU0 "0" -#define BN_P638_MAPU1 "1" +#define BN_P638_MAPU0 "0" +#define BN_P638_MAPU1 "1" /** @} */ #endif @@ -287,8 +287,25 @@ #define B12_P638_Y1 "3795191221DB4917EEE4B7B85BC7D7CA0C60E82116064463FED0892BA82ACECF905E6DB8083C5F589F04DB80E3203C1B2BEB52ACDED6DF96FC515F36761E7152AEED13369A504FE38C4FF93860B89550" #define B12_P638_R "50F94035FF4000FFFFFFFFFFF9406BFDC0040000000000000035FB801DFFBFFFFFFFFFFFFFFF401BFF80000000000000000000FFC01" #define B12_P638_H "2D88688DBA18275F5801BFFD4DDE93725697788C46C7B4BC8050639BA17EA2158B6784CCACDDECE490643943E5376D29C71C96B894056CCCC13C3DC6AAAAAA0F89601DC2979B3721C71C71C8B38CB8AEFEEB9E1C71C71C71C4B9FED17AE51B8E38E38E38E38FC954E8C65" -#define B12_P638_MAPU0 "0" -#define B12_P638_MAPU1 "1" +#define B12_P638_MAPU0 "0" +#define B12_P638_MAPU1 "1" +/** @} */ +#endif + +#if defined(EP_ENDOM) && FP_PRIME == 1150 +/** @{ */ +#define B12_P1150_A0 "0" +#define B12_P1150_A1 "0" +#define B12_P1150_B0 "20" +#define B12_P1150_B1 "1" +#define B12_P1150_X0 "4E1E10FAFC4A9E497CA939E1A8D1CF8893750CC24D82E0ED0C492C1FA618AB2FF7A02F95B12B8234C2E42B74DF654EF090ED50AD9EBF2E727F27B6CD6F368F84AB2AF7318C02994534DE0C863AC311527D3AFC2C2A4BD1A921899BD6B02CC89106FAB128E698C87928158FD2A79AABDC262097BACA9E7B226225E82DEB020FFEA5125F8F00213F5860A0217A6CCB165" +#define B12_P1150_X1 "4E0131D6174E76582E6456DC0D1D3C32BFD89F7910DD17E18C83CD8F9C658D0448A87F327AD1B7676521B2E2E0D12C4A001431F5DEE3C3E36A543D8A380ABC3CEC68488B8793A9BF98946B6994F18EC71D843B9CA980858B48C64833D7F327BBBEDBB3255D16813D550B8456140B28C587C1415C445AE12371EDB8FDC90B2E79132DB4C91AD26BE1C1B5E88E6DEA271" +#define B12_P1150_Y0 "6DDD7AA03804184D92896703D977BE38F4185F860B61EE1D6F8D586158C7B5D50905CEDE8B9313CC447F11F0C3FD83858E89E3AF93D902990383C6016138600F6A982713E0ED83D02240F89014822BCB3B5F5CD92312019DF5CDF6E9F9133761F76FFC6A63440C4DE8795057B5C184CE94A8BF49C3C7DF5AD4A691769981CA88BA23529EAD7A474ACCFA9915566548E" +#define B12_P1150_Y1 "D302BD36809044D5F86AAD68CBB100A01B504668BF5F520D0F12C2654B5A8783E6348B69958016D814548DC1380CE8CC760CFDF7832FFC51A039C6461FF93DBFB91271969B19EACDDB805038EE619DBCFC725BB34D5D5489FBCC2603ED09B35BBA11813F15468929CF817511E890F8AB76A749AF6C7A88E495DCDA0848324A4DC0DC566B98FDEE53ED8AAE8EC2AC19C" +#define B12_P1150_R "C5C1000000000000001B30F00000000000003622EC6000034BC000057869AF00005703000575ED588100ABBDB4005D60C600000BA2C6103D98AD58000B730C000210975450006301E00100052800004000108000050000000000200000000001" +#define B12_P1150_H "10F92DB9000000000004AAEC92E000000000099D3161ABC0D94249423783DA57023447266F56A9EBD69D80C7566A16D9BA9FBE7158549609DC9A0A3AA8118DCA532B07515F0AFC55A9B3F5EF6D796B3CE40C5705D3C1A799E87E283A56736E303655930FE3A33D221A3188B1CA2886B457B6998AE042390CED049D27C756A249FBA914ED3D1CC2CA3A96C10101BDBDA7F906593201A323F4EBDE9F7D48EBA93923F5727B11CA0DF5F1E65565D555573C71EBC71C81C71C71C71CB8E38E38E390" +#define B12_P1150_MAPU0 "0" +#define B12_P1150_MAPU1 "1" /** @} */ #endif @@ -640,6 +657,69 @@ int ep2_curve_opt_b(void) { return core_get()->ep2_opt_b; } +void ep2_curve_mul_a(fp2_t c, const fp2_t a) { + ctx_t *ctx = core_get(); + + if (ep2_curve_is_twist() == RLC_EP_MTYPE) { + switch (ep_curve_opt_a()) { + case RLC_ZERO: + fp2_zero(c); + break; + case RLC_ONE: + fp2_copy(c, a); + break; + case RLC_TWO: + fp2_dbl(c, a); + break; + default: + fp_mul(c[0], a[0], ep_curve_get_a()); + fp_mul(c[1], a[1], ep_curve_get_a()); + break; + } + fp2_mul_art(c, c); + } else { + switch (ctx->ep2_opt_a) { + case RLC_ZERO: + fp2_zero(c); + break; + case RLC_ONE: + fp2_copy(c, a); + break; + case RLC_TWO: + fp2_dbl(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp2_mul_dig(c, a, ctx->ep2_a[0]); + break; +#endif + default: + fp2_mul(c, a, ctx->ep2_a); + break; + } + } +} + +void ep2_curve_mul_b(fp2_t c, const fp2_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep2_opt_b) { + case RLC_ZERO: + fp2_zero(c); + break; + case RLC_ONE: + fp2_copy(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp2_mul_dig(c, a, ctx->ep2_b[0]); + break; +#endif + default: + fp2_mul(c, a, ctx->ep2_b); + break; + } +} + int ep2_curve_is_twist(void) { return core_get()->ep2_is_twist; } @@ -781,6 +861,10 @@ void ep2_curve_set_twist(int type) { case B12_P638: ASSIGN(B12_P638); break; +#elif FP_PRIME == 1150 + case B12_P1150: + ASSIGN(B12_P1150); + break; #endif default: (void)str; diff --git a/src/epx/relic_ep2_dbl.c b/src/epx/relic_ep2_dbl.c index a1abb3d1b..b8ab8f07b 100644 --- a/src/epx/relic_ep2_dbl.c +++ b/src/epx/relic_ep2_dbl.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of doubling on elliptic prime curves over quadratic - * extensions. + * Implementation of doubling on elliptic prime curves over a quadratic + * extension field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_dbl_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -43,198 +44,41 @@ * elliptic curve. * * @param[out] r - the result. - * @param[out] s - the resulting slope. + * @param[out] s - the slope. * @param[in] p - the point to double. */ -static void ep2_dbl_basic_imp(ep2_t r, fp2_t s, const ep2_t p) { - 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 = 1/(2 * y1). */ - fp2_dbl(t0, p->y); - fp2_inv(t0, t0); - - /* t1 = 3 * x1^2 + a. */ - fp2_sqr(t1, p->x); - fp2_copy(t2, t1); - fp2_dbl(t1, t1); - fp2_add(t1, t1, t2); - - fp2_add(t1, t1, ep2_curve_get_a()); - - /* t1 = (3 * x1^2 + a)/(2 * y1). */ - fp2_mul(t1, t1, t0); - - if (s != NULL) { - fp2_copy(s, t1); - } - - /* t2 = t1^2. */ - fp2_sqr(t2, t1); - - /* x3 = t1^2 - 2 * x1. */ - fp2_dbl(t0, p->x); - fp2_sub(t0, t2, t0); - - /* y3 = t1 * (x1 - x3) - y1. */ - fp2_sub(t2, p->x, t0); - fp2_mul(t1, t1, t2); - - fp2_sub(r->y, t1, p->y); - - fp2_copy(r->x, t0); - fp2_copy(r->z, p->z); - - r->coord = BASIC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); - fp2_free(t2); - } -} +TMPL_DBL_BASIC_IMP(ep2, fp2); #endif /* EP_ADD == BASIC */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) /** - * Doubles a point represented in affine coordinates on an ordinary prime + * Doubles a point represented in projective coordinates on an ordinary prime * elliptic curve. * - * @param[out] r - the result. - * @param[in] p - the point to double. + * @param r - the result. + * @param p - the point to double. */ -static void ep2_dbl_projc_imp(ep2_t r, const ep2_t p) { - fp2_t t0, t1, t2, t3, t4, t5; - - fp2_null(t0); - fp2_null(t1); - fp2_null(t2); - fp2_null(t3); - fp2_null(t4); - fp2_null(t5); - - RLC_TRY { - fp2_new(t0); - fp2_new(t1); - fp2_new(t2); - fp2_new(t3); - fp2_new(t4); - fp2_new(t5); - - if (ep_curve_opt_a() == RLC_ZERO) { - fp2_sqr(t0, p->x); - fp2_add(t2, t0, t0); - fp2_add(t0, t2, t0); - - fp2_sqr(t3, p->y); - fp2_mul(t1, t3, p->x); - fp2_add(t1, t1, t1); - fp2_add(t1, t1, t1); - fp2_sqr(r->x, t0); - fp2_add(t2, t1, t1); - fp2_sub(r->x, r->x, t2); - fp2_mul(r->z, p->z, p->y); - fp2_add(r->z, r->z, r->z); - fp2_add(t3, t3, t3); - - fp2_sqr(t3, t3); - fp2_add(t3, t3, t3); - fp2_sub(t1, t1, r->x); - fp2_mul(r->y, t0, t1); - fp2_sub(r->y, r->y, t3); - } else { - /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ - - /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ - fp2_sqr(t0, p->x); - fp2_sqr(t1, p->y); - fp2_sqr(t2, t1); - - if (p->coord != BASIC) { - /* t3 = z1^2. */ - fp2_sqr(t3, p->z); +TMPL_DBL_PROJC_IMP(ep2, fp2); - if (ep_curve_get_a() == RLC_ZERO) { - /* z3 = 2 * y1 * z1. */ - fp2_mul(r->z, p->y, p->z); - fp2_dbl(r->z, r->z); - } else { - /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ - fp2_add(r->z, p->y, p->z); - fp2_sqr(r->z, r->z); - fp2_sub(r->z, r->z, t1); - fp2_sub(r->z, r->z, t3); - } - } else { - /* z3 = 2 * y1. */ - fp2_dbl(r->z, p->y); - } - - /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ - fp2_add(t4, p->x, t1); - fp2_sqr(t4, t4); - fp2_sub(t4, t4, t0); - fp2_sub(t4, t4, t2); - fp2_dbl(t4, t4); - - /* t5 = M = 3 * x1^2 + a * z1^4. */ - fp2_dbl(t5, t0); - fp2_add(t5, t5, t0); - if (p->coord != BASIC) { - fp2_sqr(t3, t3); - fp2_mul(t1, t3, ep2_curve_get_a()); - fp2_add(t5, t5, t1); - } else { - fp2_add(t5, t5, ep2_curve_get_a()); - } - - /* x3 = T = M^2 - 2 * S. */ - fp2_sqr(r->x, t5); - fp2_dbl(t1, t4); - fp2_sub(r->x, r->x, t1); +#endif /* EP_ADD == PROJC */ - /* y3 = M * (S - T) - 8 * y1^4. */ - fp2_dbl(t2, t2); - fp2_dbl(t2, t2); - fp2_dbl(t2, t2); - fp2_sub(t4, t4, r->x); - fp2_mul(t5, t5, t4); - fp2_sub(r->y, t5, t2); - } +#if EP_ADD == JACOB || !defined(STRIP) - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); - fp2_free(t2); - fp2_free(t3); - fp2_free(t4); - fp2_free(t5); - } -} +/** + * Doubles a point represented in Jacobian coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param p - the point to double. + */ +TMPL_DBL_JACOB_IMP(ep2, fp2); -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ - /* Public definitions */ +/* Public definitions */ /*============================================================================*/ #if EP_ADD == BASIC || !defined(STRIP) @@ -244,7 +88,6 @@ void ep2_dbl_basic(ep2_t r, const ep2_t p) { ep2_set_infty(r); return; } - ep2_dbl_basic_imp(r, NULL, p); } @@ -259,7 +102,7 @@ void ep2_dbl_slp_basic(ep2_t r, fp2_t s, const ep2_t p) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep2_dbl_projc(ep2_t r, const ep2_t p) { if (ep2_is_infty(p)) { @@ -271,3 +114,16 @@ void ep2_dbl_projc(ep2_t r, const ep2_t p) { } #endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep2_dbl_jacob(ep2_t r, const ep2_t p) { + if (ep2_is_infty(p)) { + ep2_set_infty(r); + return; + } + + ep2_dbl_jacob_imp(r, p); +} + +#endif diff --git a/src/epx/relic_ep2_frb.c b/src/epx/relic_ep2_frb.c index b43695e04..2b330927f 100644 --- a/src/epx/relic_ep2_frb.c +++ b/src/epx/relic_ep2_frb.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of frobenius action on prime elliptic curves over - * quadratic extensions. + * Implementation of frobenius action on prime elliptic curves over a quadratic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep2_map.c b/src/epx/relic_ep2_map.c index 229d5f349..2445deed3 100644 --- a/src/epx/relic_ep2_map.c +++ b/src/epx/relic_ep2_map.c @@ -25,14 +25,14 @@ * @file * * Implementation of hashing to a prime elliptic curve over a quadratic - * extension. + * extension field. * * @ingroup epx */ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" +#include "relic_ep_map_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -58,19 +58,12 @@ TMPL_MAP_ISOGENY_MAP(ep2, fp2, iso2) /** * Simplified SWU mapping. */ -#define EP2_MAP_COPY_COND(O, I, C) \ - do { \ - dv_copy_cond(O[0], I[0], RLC_FP_DIGS, C); \ - dv_copy_cond(O[1], I[1], RLC_FP_DIGS, C); \ - } while (0) -TMPL_MAP_SSWU(ep2, fp2, fp_t, EP2_MAP_COPY_COND) +TMPL_MAP_SSWU(ep2, fp2, fp_t) /** * Shallue--van de Woestijne map. */ -TMPL_MAP_SVDW(ep2, fp2, fp_t, EP2_MAP_COPY_COND) - -#undef EP2_MAP_COPY_COND +TMPL_MAP_SVDW(ep2, fp2, fp_t) /* caution: this function overwrites k, which it uses as an auxiliary variable */ static inline int fp2_sgn0(const fp2_t t, bn_t k) { @@ -140,8 +133,7 @@ static void ep2_map_from_field(ep2_t p, const uint8_t *r, size_t len) { /* compare sign of y to sign of t; fix if necessary */ \ neg = neg != fp2_sgn0(PT->y, k); \ fp2_neg(t, PT->y); \ - dv_copy_cond(PT->y[0], t[0], RLC_FP_DIGS, neg); \ - dv_copy_cond(PT->y[1], t[1], RLC_FP_DIGS, neg); \ + fp2_copy_sec(PT->y, t, neg); \ } while (0) /* first map invocation */ @@ -201,7 +193,7 @@ void ep2_map_basic(ep2_t p, const uint8_t *msg, size_t len) { fp2_set_dig(p->z, 1); while (1) { - ep2_rhs(t0, p); + ep2_rhs(t0, p->x); if (fp2_is_sqr(t0) == 1) { fp2_srt(p->y, t0); @@ -257,12 +249,18 @@ void ep2_map_swift(ep2_t p, const uint8_t *msg, size_t len) { /* enough space for two field elements plus extra bytes for uniformity */ const size_t elm = (FP_PRIME + ep_param_level() + 7) / 8; uint8_t t0z, t0, t1, sign, *r = RLC_ALLOCA(uint8_t, 4 * elm + 1); - fp2_t t, u, v, w, y, x1, y1, z1; + fp2_t a, b, c, d, e, f, t, u, v, w, y, x1, y1, z1, den[3]; ctx_t *ctx = core_get(); dig_t c2, c3; bn_t k; bn_null(k); + fp2_null(a); + fp2_null(b); + fp2_null(c); + fp2_null(d); + fp2_null(e); + fp2_null(f); fp2_null(t); fp2_null(u); fp2_null(v); @@ -274,6 +272,12 @@ void ep2_map_swift(ep2_t p, const uint8_t *msg, size_t len) { RLC_TRY { bn_new(k); + fp2_new(a); + fp2_new(b); + fp2_new(c); + fp2_new(d); + fp2_new(e); + fp2_new(f); fp2_new(t); fp2_new(u); fp2_new(v); @@ -296,85 +300,216 @@ void ep2_map_swift(ep2_t p, const uint8_t *msg, size_t len) { sign = r[0] & 1; r -= 4 * elm; - /* Assume that a = 0. */ - fp2_sqr(x1, u); - fp2_mul(x1, x1, u); - fp2_sqr(y1, t); - fp2_add(x1, x1, ctx->ep2_b); - fp2_sub(x1, x1, y1); - fp2_dbl(y1, y1); - fp2_add(y1, y1, x1); - fp2_copy(z1, u); - fp_mul(z1[0], z1[0], ctx->ep_map_c[4]); - fp_mul(z1[1], z1[1], ctx->ep_map_c[4]); - fp2_mul(x1, x1, z1); - fp2_mul(z1, z1, t); - fp2_dbl(z1, z1); - - fp2_dbl(y, y1); - fp2_sqr(y, y); - fp2_mul(v, y1, u); - fp2_sub(v, x1, v); - fp2_mul(v, v, z1); - fp2_mul(w, y1, z1); - fp2_dbl(w, w); - - if (fp2_is_zero(w)) { - ep2_set_infty(p); - } else { - fp2_inv(w, w); - fp2_mul(x1, v, w); - fp2_add(y1, u, x1); - fp2_neg(y1, y1); - fp2_mul(z1, y, w); - fp2_sqr(z1, z1); - fp2_add(z1, z1, u); - - fp2_sqr(t, x1); - fp2_mul(t, t, x1); - fp2_add(t, t, ctx->ep2_b); - - fp2_sqr(u, y1); - fp2_mul(u, u, y1); - fp2_add(u, u, ctx->ep2_b); - - fp2_sqr(v, z1); - fp2_mul(v, v, z1); - fp2_add(v, v, ctx->ep2_b); - - c2 = fp2_is_sqr(u); - c3 = fp2_is_sqr(v); - - for (int i = 0; i < 2; i++) { - dv_swap_cond(x1[i], y1[i], RLC_FP_DIGS, c2); - dv_swap_cond(t[i], u[i], RLC_FP_DIGS, c2); - dv_swap_cond(x1[i], z1[i], RLC_FP_DIGS, c3); - dv_swap_cond(t[i], v[i], RLC_FP_DIGS, c3); + if (ep2_curve_opt_b() == RLC_ZERO) { + fp2_sqr(a, u); + fp2_sqr(b, a); + fp2_mul(c, b, a); + if (ep2_curve_opt_a() == RLC_ONE) { + fp2_add_dig(c, c, 64); + } else { + fp2_dbl(f, ep2_curve_get_a()); + fp2_dbl(f, f); + fp2_sqr(e, f); + fp2_mul(e, e, f); + fp2_add(c, c, e); } - - if (!fp2_srt(t, t)) { + fp2_sqr(d, t); + + fp2_mul(v, a, d); + fp2_mul(v, v, u); + fp2_mul_dig(v, v, 24); + fp_mul(v[0], v[0], ctx->ep_map_c[4]); + fp_mul(v[1], v[1], ctx->ep_map_c[4]); + + fp_sub_dig(p->x[0], ctx->ep_map_c[4], 1); + fp_hlv(p->x[0], p->x[0]); + + fp2_sqr(w, b); + fp2_mul(y, v, a); + if (ep2_curve_opt_a() == RLC_ONE) { + fp2_dbl(t, c); + fp2_dbl(t, t); + } else { + fp2_mul(t, f, c); + } + fp2_add(y, y, t); + fp_mul(y[0], y[0], p->x[0]); + fp_mul(y[1], y[1], p->x[0]); + + fp2_add(den[0], c, v); + fp2_mul(den[0], den[0], u); + fp_mul(den[0][0], den[0][0], ctx->ep_map_c[4]); + fp_mul(den[0][1], den[0][1], ctx->ep_map_c[4]); + fp_mul(den[0][0], den[0][0], p->x[0]); + fp_mul(den[0][1], den[0][1], p->x[0]); + fp2_dbl(den[0], den[0]); + fp2_neg(den[0], den[0]); + fp_mul(den[1][0], den[0][0], p->x[0]); + fp_mul(den[1][1], den[0][1], p->x[0]); + if (ep_curve_opt_a() == RLC_ONE) { + fp2_sub_dig(den[2], a, 4); + } else { + fp2_sub(den[2], a, f); + } + fp2_sqr(den[2], den[2]); + fp2_mul_dig(den[2], den[2], 216); + fp2_dbl(den[2], den[2]); + fp2_neg(den[2], den[2]); + fp2_mul(den[2], den[2], b); + fp2_mul(den[2], den[2], d); + + if (fp2_is_zero(den[0]) || fp2_is_zero(den[1]) || fp2_is_zero(den[2])) { + ep2_set_infty(p); + } else { + fp2_inv_sim(den, den, 3); + if (ep2_curve_opt_a() == RLC_ONE) { + fp2_dbl(a, a); + fp2_dbl(a, a); + fp2_dbl(a, a); + fp2_dbl(a, a); + fp2_add(y1, a, v); + fp2_dbl(y1, y1); + fp2_dbl(y1, y1); + } else { + fp2_mul(y1, f, v); + fp2_mul(u, a, e); + fp2_add(y1, y1, u); + } + fp2_add(y1, y1, w); + fp_mul(z1[0], y[0], p->x[0]); + fp_mul(z1[1], y[1], p->x[0]); + fp2_add(x1, y1, z1); + fp2_add(y1, y1, y); + + if (ep2_curve_opt_a() == RLC_ONE) { + fp2_dbl(e, b); + fp2_dbl(e, e); + fp2_add(z1, a, e); + } else { + fp2_mul(z1, f, a); + fp2_add(z1, z1, b); + fp2_mul(z1, z1, f); + } + fp2_dbl(t, z1); + fp2_add(z1, z1, t); + fp2_sub(z1, c, z1); + fp2_sub(z1, z1, v); + fp2_mul(z1, z1, v); + if (ep2_curve_opt_a() == RLC_ONE) { + fp2_dbl(a, a); + fp2_dbl(a, a); + fp2_dbl(a, a); + fp2_set_dig(d, 64); + fp2_sqr(d, d); + } else { + fp2_dbl(a, u); + fp2_sqr(d, e); + } + fp2_add(a, a, w); + fp2_mul(u, a, b); + fp2_sub(z1, u, z1); + fp2_add(z1, z1, d); + + fp2_mul(x1, x1, den[0]); + fp2_mul(y1, y1, den[1]); + fp2_mul(z1, z1, den[2]); + + ep2_rhs(t, x1); + ep2_rhs(u, y1); + ep2_rhs(v, z1); + + int c2 = fp2_is_sqr(u); + int c3 = fp2_is_sqr(v); + + fp2_copy_sec(t, u, c2); + fp2_copy_sec(x1, y1, c2); + fp2_copy_sec(t, v, c3); + fp2_copy_sec(x1, z1, c3); + + if (!fp2_srt(t, t)) { + RLC_THROW(ERR_NO_VALID); + } + fp2_neg(u, t); + fp2_copy_sec(t, u, fp_is_even(t[0]) ^ sign); + + fp2_copy(p->x, x1); + fp2_copy(p->y, t); + fp2_set_dig(p->z, 1); + p->coord = BASIC; + } + } else { + if (ep2_curve_opt_a() != RLC_ZERO) { RLC_THROW(ERR_NO_VALID); + } else { + /* Assume that a = 0. */ + fp2_sqr(x1, u); + fp2_mul(x1, x1, u); + fp2_sqr(y1, t); + fp2_add(x1, x1, ctx->ep2_b); + fp2_sub(x1, x1, y1); + fp2_dbl(y1, y1); + fp2_add(y1, y1, x1); + fp2_copy(z1, u); + fp_mul(z1[0], z1[0], ctx->ep_map_c[4]); + fp_mul(z1[1], z1[1], ctx->ep_map_c[4]); + fp2_mul(x1, x1, z1); + fp2_mul(z1, z1, t); + fp2_dbl(z1, z1); + + fp2_dbl(y, y1); + fp2_sqr(y, y); + fp2_mul(v, y1, u); + fp2_sub(v, x1, v); + fp2_mul(v, v, z1); + fp2_mul(w, y1, z1); + fp2_dbl(w, w); + + if (fp2_is_zero(w)) { + ep2_set_infty(p); + } else { + fp2_inv(w, w); + fp2_mul(x1, v, w); + fp2_add(y1, u, x1); + fp2_neg(y1, y1); + fp2_mul(z1, y, w); + fp2_sqr(z1, z1); + fp2_add(z1, z1, u); + + ep2_rhs(t, x1); + ep2_rhs(u, y1); + ep2_rhs(v, z1); + + c2 = fp2_is_sqr(u); + c3 = fp2_is_sqr(v); + + fp2_copy_sec(x1, y1, c2); + fp2_copy_sec(t, u, c2); + fp2_copy_sec(x1, z1, c3); + fp2_copy_sec(t, v, c3); + + if (!fp2_srt(t, t)) { + RLC_THROW(ERR_NO_VALID); + } + + t0z = fp_is_zero(t[0]); + fp_prime_back(k, t[0]); + t0 = bn_get_bit(k, 0); + fp_prime_back(k, t[1]); + t1 = bn_get_bit(k, 0); + /* t[0] == 0 ? sgn0(t[1]) : sgn0(t[0]) */ + sign ^= (t0 | (t0z & t1)); + + fp2_neg(u, t); + fp2_copy_sec(t, u, sign); + + fp2_copy(p->x, x1); + fp2_copy(p->y, t); + fp2_set_dig(p->z, 1); + p->coord = BASIC; + } } - - t0z = fp_is_zero(t[0]); - fp_prime_back(k, t[0]); - t0 = bn_get_bit(k, 0); - fp_prime_back(k, t[1]); - t1 = bn_get_bit(k, 0); - /* t[0] == 0 ? sgn0(t[1]) : sgn0(t[0]) */ - sign ^= (t0 | (t0z & t1)); - - fp2_neg(u, t); - dv_swap_cond(t[0], u[0], RLC_FP_DIGS, sign); - dv_swap_cond(t[1], u[1], RLC_FP_DIGS, sign); - - fp2_copy(p->x, x1); - fp2_copy(p->y, t); - fp2_set_dig(p->z, 1); - p->coord = BASIC; - - ep2_mul_cof(p, p); } + ep2_mul_cof(p, p); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/epx/relic_ep2_mul.c b/src/epx/relic_ep2_mul.c index 698f026b6..68904d8f5 100644 --- a/src/epx/relic_ep2_mul.c +++ b/src/epx/relic_ep2_mul.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point multiplication on prime elliptic curves over - * quadratic extensions. + * Implementation of point multiplication on prime elliptic curves over a + * quadratic extension field. * * @ingroup epx */ @@ -36,11 +36,11 @@ /* Private definitions */ /*============================================================================*/ -#if EP_MUL == LWNAF || !defined(STRIP) - #if defined(EP_ENDOM) -static void ep2_mul_glv_imp(ep2_t r, const ep2_t p, const bn_t k) { +#if EP_MUL == LWNAF || !defined(STRIP) + +static void ep2_mul_gls_imp(ep2_t r, const ep2_t p, const bn_t k) { size_t l, _l[4]; bn_t n, _k[4], u; int8_t naf[4][RLC_FP_BITS + 1]; @@ -110,10 +110,133 @@ static void ep2_mul_glv_imp(ep2_t r, const ep2_t p, const bn_t k) { } } +#endif /* EP_MUL == LWNAF */ + +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep2_mul_reg_gls(ep2_t r, const ep2_t p, const bn_t k) { + int8_t reg[4][RLC_FP_BITS + 1], b[4], s[4], c0, n0; + ep2_t q, w, t[4][1 << (RLC_WIDTH - 2)]; + bn_t n, _k[4], u; + size_t l, len, _l[4]; + + bn_null(n); + bn_null(u); + ep2_null(q); + ep2_null(w); + + RLC_TRY { + bn_new(n); + bn_new(u); + ep2_new(q); + ep2_new(w); + for (size_t i = 0; i < 4; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep2_null(t[i][j]); + ep2_new(t[i][j]); + } + } + + ep2_curve_get_ord(n); + fp_prime_get_par(u); + bn_mod(_k[0], k, n); + bn_rec_frb(_k, 4, _k[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + /* Make some extra room for BN curves that grow subscalars by 1. */ + len = bn_bits(u) + (ep_curve_is_pairf() == EP_BN); + ep2_norm(t[0][0], p); + for (size_t i = 0; i < 4; i++) { + s[i] = bn_sign(_k[i]); + bn_abs(_k[i], _k[i]); + b[i] = bn_is_even(_k[i]); + _k[i]->dp[0] |= b[i]; + + _l[i] = RLC_FP_BITS + 1; + bn_rec_reg(reg[i], &_l[i], _k[i], len, RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + ep2_frb(t[i][0], t[i - 1][0], 1); + } + } + + for (size_t i = 0; i < 4; i++) { + ep2_neg(q, t[i][0]); + fp2_copy_sec(q->y, t[i][0]->y, s[i] == RLC_POS); + ep2_tab(t[i], q, RLC_WIDTH); + } + +#if defined(EP_MIXED) + fp2_set_dig(w->z, 1); + w->coord = BASIC; +#else + w->coord = = EP_ADD; +#endif + + ep2_set_infty(r); + for (int j = l - 1; j >= 0; j--) { + for (size_t i = 0; i < RLC_WIDTH - 1; i++) { + ep2_dbl(r, r); + } + + for (size_t i = 0; i < 4; i++) { + n0 = reg[i][j]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + + for (size_t m = 0; m < (1 << (RLC_WIDTH - 2)); m++) { + fp2_copy_sec(w->x, t[i][m]->x, m == n0); + fp2_copy_sec(w->y, t[i][m]->y, m == n0); + #if !defined(EP_MIXED) + fp2_copy_sec(w->z, t[i][m]->z, m == n0); + #endif + } + + ep2_neg(q, w); + fp2_copy_sec(q->y, w->y, c0 == 0); + ep2_add(r, r, q); + } + } + + for (size_t i = 0; i < 4; i++) { + /* Tables are built with points already negated, so no need here. */ + ep2_sub(q, r, t[i][0]); + fp2_copy_sec(r->x, q->x, b[i]); + fp2_copy_sec(r->y, q->y, b[i]); + fp2_copy_sec(r->z, q->z, b[i]); + } + + /* Convert r to affine coordinates. */ + ep2_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + ep2_free(q); + ep2_free(w); + for (int i = 0; i < 4; i++) { + bn_free(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep2_free(t[i][j]); + } + } + } +} + +#endif /* EP_MUL == LWREG */ #endif /* EP_ENDOM */ #if defined(EP_PLAIN) || defined(EP_SUPER) +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep2_mul_naf_imp(ep2_t r, const ep2_t p, const bn_t k) { size_t l; int8_t n, naf[RLC_FP_BITS + 1]; @@ -161,9 +284,95 @@ static void ep2_mul_naf_imp(ep2_t r, const ep2_t p, const bn_t k) { } } -#endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_MUL == LWNAF */ +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep2_mul_reg_imp(ep2_t r, const ep2_t p, const bn_t k) { + bn_t _k; + int8_t s, reg[1 + RLC_CEIL(RLC_FP_BITS + 1, RLC_WIDTH - 1)]; + ep2_t t[1 << (RLC_WIDTH - 2)], u, v; + size_t l, n; + + bn_null(_k); + + RLC_TRY { + bn_new(_k); + ep2_new(u); + ep2_new(v); + /* Prepare the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep2_null(t[i]); + ep2_new(t[i]); + } + /* Compute the precomputation table. */ + ep2_tab(t, p, RLC_WIDTH); + + ep2_curve_get_ord(_k); + n = bn_bits(_k); + + /* Make a copy of the scalar for processing. */ + bn_abs(_k, k); + _k->dp[0] |= 1; + + /* Compute the regular w-NAF representation of k. */ + l = RLC_CEIL(n, RLC_WIDTH - 1) + 1; + bn_rec_reg(reg, &l, _k, n, RLC_WIDTH); + +#if defined(EP_MIXED) + fp2_set_dig(u->z, 1); + u->coord = BASIC; +#else + u->coord = EP_ADD; +#endif + ep2_set_infty(r); + for (int i = l - 1; i >= 0; i--) { + for (size_t j = 0; j < RLC_WIDTH - 1; j++) { + ep2_dbl(r, r); + } + + n = reg[i]; + s = (n >> 7); + n = ((n ^ s) - s) >> 1; + + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + fp2_copy_sec(u->x, t[j]->x, j == n); + fp2_copy_sec(u->y, t[j]->y, j == n); +#if !defined(EP_MIXED) + fp_copy_sec(u->z, t[j]->z, j == n); +#endif + } + ep2_neg(v, u); + fp2_copy_sec(u->y, v->y, s != 0); + ep2_add(r, r, u); + } + /* t[0] has an unmodified copy of p. */ + ep2_sub(u, r, t[0]); + fp2_copy_sec(r->x, u->x, bn_is_even(k)); + fp2_copy_sec(r->y, u->y, bn_is_even(k)); + fp2_copy_sec(r->z, u->z, bn_is_even(k)); + /* Convert r to affine coordinates. */ + ep2_norm(r, r); + ep2_neg(u, r); + fp2_copy_sec(r->y, u->y, bn_sign(k) == RLC_NEG); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep2_free(t[i]); + } + bn_free(_k); + ep2_free(u); + ep2_free(v); + } +} + +#endif /* EP_MUL == LWREG */ +#endif /* EP_PLAIN || EP_SUPER */ + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -326,7 +535,7 @@ void ep2_mul_monty(ep2_t r, const ep2_t p, const bn_t k) { bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); - dv_swap_cond(l->dp, n->dp, RLC_MAX(l->used, n->used), + dv_swap_sec(l->dp, n->dp, RLC_MAX(l->used, n->used), bn_get_bit(l, bits) == 0); l->used = RLC_SEL(l->used, n->used, bn_get_bit(l, bits) == 0); @@ -339,20 +548,20 @@ void ep2_mul_monty(ep2_t r, const ep2_t p, const bn_t k) { for (int i = bits - 1; i >= 0; i--) { int j = bn_get_bit(l, i); - dv_swap_cond(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); ep2_add(t[0], t[0], t[1]); ep2_dbl(t[1], t[1]); - dv_swap_cond(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); } ep2_norm(r, t[0]); @@ -380,7 +589,7 @@ void ep2_mul_lwnaf(ep2_t r, const ep2_t p, const bn_t k) { #if defined(EP_ENDOM) if (ep_curve_is_endom()) { - ep2_mul_glv_imp(r, p, k); + ep2_mul_gls_imp(r, p, k); return; } #endif @@ -392,6 +601,28 @@ void ep2_mul_lwnaf(ep2_t r, const ep2_t p, const bn_t k) { #endif +#if EP_MUL == LWREG || !defined(STRIP) + +void ep2_mul_lwreg(ep2_t r, const ep2_t p, const bn_t k) { + if (bn_is_zero(k) || ep2_is_infty(p)) { + ep2_set_infty(r); + return; + } + +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + ep2_mul_reg_gls(r, p, k); + return; + } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + ep2_mul_reg_imp(r, p, k); +#endif +} + +#endif + void ep2_mul_gen(ep2_t r, const bn_t k) { if (bn_is_zero(k)) { ep2_set_infty(r); diff --git a/src/epx/relic_ep2_mul_cof.c b/src/epx/relic_ep2_mul_cof.c index ee8be325a..edc10dd2b 100644 --- a/src/epx/relic_ep2_mul_cof.c +++ b/src/epx/relic_ep2_mul_cof.c @@ -25,14 +25,13 @@ * @file * * Implementation of point multiplication of a prime elliptic curve over a - * quadratic extension by the curve cofactor. + * quadratic extension field by the curve cofactor. * * @ingroup epx */ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Private definitions */ @@ -166,7 +165,7 @@ void ep2_mul_cof(ep2_t r, const ep2_t p) { default: /* Now, multiply by cofactor to get the correct group. */ ep2_curve_get_cof(k); - ep2_mul_basic(r, p, k); + ep2_mul_big(r, p, k); break; } } RLC_CATCH_ANY { diff --git a/src/epx/relic_ep2_mul_fix.c b/src/epx/relic_ep2_mul_fix.c index 075c9227a..200db4c89 100644 --- a/src/epx/relic_ep2_mul_fix.c +++ b/src/epx/relic_ep2_mul_fix.c @@ -25,7 +25,7 @@ * @file * * Implementation of fixed point multiplication on a prime elliptic curve over - * a quadratic extension. + * a quadratic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep2_mul_sim.c b/src/epx/relic_ep2_mul_sim.c index 51f9f8df6..c39c432f6 100644 --- a/src/epx/relic_ep2_mul_sim.c +++ b/src/epx/relic_ep2_mul_sim.c @@ -25,7 +25,7 @@ * @file * * Implementation of simultaneous point multiplication on a prime elliptic - * curve over a quadratic extension. + * curve over a quadratic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep2_neg.c b/src/epx/relic_ep2_neg.c index bde5c68de..16225e986 100644 --- a/src/epx/relic_ep2_neg.c +++ b/src/epx/relic_ep2_neg.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point negation on elliptic prime curves over quadratic - * extensions. + * Implementation of point negation on elliptic prime curves over a quadratic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep2_norm.c b/src/epx/relic_ep2_norm.c index 3276649d3..0010b976a 100644 --- a/src/epx/relic_ep2_norm.c +++ b/src/epx/relic_ep2_norm.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point normalization on prime elliptic curves over quadratic - * extensions. + * Implementation of point normalization on prime elliptic curves over a + * quadratic extension. * * @ingroup epx */ @@ -43,36 +43,45 @@ * * @param r - the result. * @param p - the point to normalize. + * @param inv - the flag to indicate if z is already inverted. */ -static void ep2_norm_imp(ep2_t r, const ep2_t p, int inverted) { +static void ep2_norm_imp(ep2_t r, const ep2_t p, int inv) { if (p->coord != BASIC) { - fp2_t t0, t1; + fp2_t t; - fp2_null(t0); - fp2_null(t1); + fp2_null(t); RLC_TRY { + fp2_new(t); - fp2_new(t0); - fp2_new(t1); - - if (inverted) { - fp2_copy(t1, p->z); + if (inv) { + fp2_copy(r->z, p->z); } else { - fp2_inv(t1, p->z); + fp2_inv(r->z, p->z); + } + + switch (p->coord) { + case PROJC: + fp2_mul(r->x, p->x, r->z); + fp2_mul(r->y, p->y, r->z); + break; + case JACOB: + fp2_sqr(t, r->z); + fp2_mul(r->x, p->x, t); + fp2_mul(t, t, r->z); + fp2_mul(r->y, p->y, t); + break; + default: + ep2_copy(r, p); + break; } - fp2_sqr(t0, t1); - fp2_mul(r->x, p->x, t0); - fp2_mul(t0, t0, t1); - fp2_mul(r->y, p->y, t0); fp2_set_dig(r->z, 1); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { - fp2_free(t0); - fp2_free(t1); + fp2_free(t); } } @@ -92,17 +101,18 @@ void ep2_norm(ep2_t r, const ep2_t p) { } if (p->coord == BASIC) { - /* If the point is represented in affine coordinates, we just copy it. */ + /* If the point is represented in affine coordinates, just copy it. */ ep2_copy(r, p); + return; } #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) ep2_norm_imp(r, p, 0); -#endif +#endif /* EP_ADD == PROJC */ } void ep2_norm_sim(ep2_t *r, const ep2_t *t, int n) { int i; - fp2_t *a = RLC_ALLOCA(fp2_t, n); + fp2_t* a = RLC_ALLOCA(fp2_t, n); RLC_TRY { if (a == NULL) { @@ -114,19 +124,20 @@ void ep2_norm_sim(ep2_t *r, const ep2_t *t, int n) { fp2_copy(a[i], t[i]->z); } - fp2_inv_sim(a, a, n); + fp2_inv_sim(a, (const fp2_t *)a, n); for (i = 0; i < n; i++) { fp2_copy(r[i]->x, t[i]->x); fp2_copy(r[i]->y, t[i]->y); - fp2_copy(r[i]->z, a[i]); + if (!ep2_is_infty(t[i])) { + fp2_copy(r[i]->z, a[i]); + } } - #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) for (i = 0; i < n; i++) { ep2_norm_imp(r[i], r[i], 1); } -#endif +#endif /* EP_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/epx/relic_ep2_pck.c b/src/epx/relic_ep2_pck.c index 699ebde41..6fd8e2abd 100644 --- a/src/epx/relic_ep2_pck.c +++ b/src/epx/relic_ep2_pck.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point compression on prime elliptic curves over quadratic - * extensions. + * Implementation of point compression on prime elliptic curves over a quadratic + * extension field. * * @ingroup epx */ @@ -85,7 +85,7 @@ int ep2_upk(ep2_t r, const ep2_t p) { bn_new(halfQ); bn_new(yValue); - ep2_rhs(t, p); + ep2_rhs(t, p->x); /* t0 = sqrt(x1^3 + a * x1 + b). */ result = fp2_srt(t, t); diff --git a/src/epx/relic_ep2_util.c b/src/epx/relic_ep2_util.c index b61668ace..4ac588532 100644 --- a/src/epx/relic_ep2_util.c +++ b/src/epx/relic_ep2_util.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of comparison for points on prime elliptic curves over - * quadratic extensions. + * Implementation of comparison for points on prime elliptic curves over a + * quadratic extension field. * * @ingroup epx */ @@ -89,13 +89,18 @@ void ep2_blind(ep2_t r, const ep2_t p) { #if EP_ADD == BASIC (void)rand; ep2_copy(r, p); -#else +#elif EP_ADD == PROJC + fp2_mul(r->x, p->x, rand); + fp2_mul(r->y, p->y, rand); + fp2_mul(r->z, p->z, rand); + r->coord = PROJC; +#elif EP_ADD == JACOB fp2_mul(r->z, p->z, rand); fp2_mul(r->y, p->y, rand); fp2_sqr(rand, rand); fp2_mul(r->x, r->x, rand); fp2_mul(r->y, r->y, rand); - r->coord = EP_ADD; + r->coord = JACOB; #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -104,7 +109,7 @@ void ep2_blind(ep2_t r, const ep2_t p) { } } -void ep2_rhs(fp2_t rhs, const ep2_t p) { +void ep2_rhs(fp2_t rhs, const fp2_t x) { fp2_t t0; fp2_null(t0); @@ -112,7 +117,7 @@ void ep2_rhs(fp2_t rhs, const ep2_t p) { RLC_TRY { fp2_new(t0); - fp2_sqr(t0, p->x); /* x1^2 */ + fp2_sqr(t0, x); /* x1^2 */ switch (ep2_curve_opt_a()) { case RLC_ZERO: @@ -136,7 +141,7 @@ void ep2_rhs(fp2_t rhs, const ep2_t p) { break; } - fp2_mul(t0, t0, p->x); /* x1^3 + a * x */ + fp2_mul(t0, t0, x); /* x1^3 + a * x */ switch (ep2_curve_opt_b()) { case RLC_ZERO: @@ -180,7 +185,7 @@ int ep2_on_curve(const ep2_t p) { ep2_norm(t, p); - ep2_rhs(t->x, t); + ep2_rhs(t->x, t->x); fp2_sqr(t->y, t->y); r = (fp2_cmp(t->x, t->y) == RLC_EQ) || ep2_is_infty(p); diff --git a/src/epx/relic_ep3_add.c b/src/epx/relic_ep3_add.c index 3c3626342..d8a7667a6 100644 --- a/src/epx/relic_ep3_add.c +++ b/src/epx/relic_ep3_add.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of addition on prime elliptic curves over quadratic - * extensions. + * Implementation of addition on prime elliptic curves over a cubic extension + * field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,312 +43,62 @@ * 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 */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) -#if defined(EP_MIXED) || !defined(STRIP) +/** + * Adds a point represented in homogeneous coordinates to a point represented in + * 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. + */ +TMPL_ADD_PROJC_MIX(ep3, fp3); /** - * Adds a point represented in affine coordinates to a point represented in - * projective coordinates. + * Adds two points represented in homogeneous coordinates on an ordinary prime + * elliptic curve. * - * @param r - the result. - * @param s - the slope. - * @param p - the affine point. - * @param q - the projective point. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep3_add_projc_mix(ep3_t r, const ep3_t p, const ep3_t q) { - fp3_t t0, t1, t2, t3, t4, t5, t6; +TMPL_ADD_PROJC_IMP(ep3, fp3); - fp3_null(t0); - fp3_null(t1); - fp3_null(t2); - fp3_null(t3); - fp3_null(t4); - fp3_null(t5); - fp3_null(t6); +#endif /* EP_ADD == PROJC */ - RLC_TRY { - fp3_new(t0); - fp3_new(t1); - fp3_new(t2); - fp3_new(t3); - fp3_new(t4); - fp3_new(t5); - fp3_new(t6); - - if (p->coord != BASIC) { - /* t0 = z1^2. */ - fp3_sqr(t0, p->z); - - /* t3 = U2 = x2 * z1^2. */ - fp3_mul(t3, q->x, t0); - - /* t1 = S2 = y2 * z1^3. */ - fp3_mul(t1, t0, p->z); - fp3_mul(t1, t1, q->y); - - /* t3 = H = U2 - x1. */ - fp3_sub(t3, t3, p->x); - - /* t1 = R = 2 * (S2 - y1). */ - fp3_sub(t1, t1, p->y); - } else { - /* H = x2 - x1. */ - fp3_sub(t3, q->x, p->x); - - /* t1 = R = 2 * (y2 - y1). */ - fp3_sub(t1, q->y, p->y); - } - - /* t2 = HH = H^2. */ - fp3_sqr(t2, t3); - - /* If E is zero. */ - if (fp3_is_zero(t3)) { - if (fp3_is_zero(t1)) { - /* If I is zero, p = q, should have doubled. */ - ep3_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep3_set_infty(r); - } - } else { - /* t5 = J = H * HH. */ - fp3_mul(t5, t3, t2); - - /* t4 = V = x1 * HH. */ - fp3_mul(t4, p->x, t2); - - /* x3 = R^2 - J - 2 * V. */ - fp3_sqr(r->x, t1); - fp3_sub(r->x, r->x, t5); - fp3_dbl(t6, t4); - fp3_sub(r->x, r->x, t6); - - /* y3 = R * (V - x3) - Y1 * J. */ - fp3_sub(t4, t4, r->x); - fp3_mul(t4, t4, t1); - fp3_mul(t1, p->y, t5); - fp3_sub(r->y, t4, t1); - - if (p->coord != BASIC) { - /* z3 = z1 * H. */ - fp3_mul(r->z, p->z, t3); - } else { - /* z3 = H. */ - fp3_copy(r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); - fp3_free(t2); - fp3_free(t3); - fp3_free(t4); - fp3_free(t5); - fp3_free(t6); - } -} +#if EP_ADD == JACOB || !defined(STRIP) -#endif +/** + * Adds a point represented in Jacobian coordinates to a point represented in + * 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. + */ +TMPL_ADD_JACOB_MIX(ep3, fp3); /** - * Adds two points represented in projective coordinates on an ordinary prime + * Adds two points represented in Jacobian coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep3_add_projc_imp(ep3_t r, const ep3_t p, const ep3_t q) { -#if defined(EP_MIXED) && defined(STRIP) - ep3_add_projc_mix(r, p, q); -#else /* General addition. */ - fp3_t t0, t1, t2, t3, t4, t5, t6; - - fp3_null(t0); - fp3_null(t1); - fp3_null(t2); - fp3_null(t3); - fp3_null(t4); - fp3_null(t5); - fp3_null(t6); +TMPL_ADD_JACOB_IMP(ep3, fp3); - RLC_TRY { - fp3_new(t0); - fp3_new(t1); - fp3_new(t2); - fp3_new(t3); - fp3_new(t4); - fp3_new(t5); - fp3_new(t6); - - if (q->coord == BASIC) { - ep3_add_projc_mix(r, p, q); - } else { - /* t0 = z1^2. */ - fp3_sqr(t0, p->z); - - /* t1 = z2^2. */ - fp3_sqr(t1, q->z); - - /* t2 = U1 = x1 * z2^2. */ - fp3_mul(t2, p->x, t1); - - /* t3 = U2 = x2 * z1^2. */ - fp3_mul(t3, q->x, t0); - - /* t6 = z1^2 + z2^2. */ - fp3_add(t6, t0, t1); - - /* t0 = S2 = y2 * z1^3. */ - fp3_mul(t0, t0, p->z); - fp3_mul(t0, t0, q->y); - - /* t1 = S1 = y1 * z2^3. */ - fp3_mul(t1, t1, q->z); - fp3_mul(t1, t1, p->y); - - /* t3 = H = U2 - U1. */ - fp3_sub(t3, t3, t2); - - /* t0 = R = 2 * (S2 - S1). */ - fp3_sub(t0, t0, t1); - - fp3_dbl(t0, t0); - - /* If E is zero. */ - if (fp3_is_zero(t3)) { - if (fp3_is_zero(t0)) { - /* If I is zero, p = q, should have doubled. */ - ep3_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep3_set_infty(r); - } - } else { - /* t4 = I = (2*H)^2. */ - fp3_dbl(t4, t3); - fp3_sqr(t4, t4); - - /* t5 = J = H * I. */ - fp3_mul(t5, t3, t4); - - /* t4 = V = U1 * I. */ - fp3_mul(t4, t2, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp3_sqr(r->x, t0); - fp3_sub(r->x, r->x, t5); - fp3_dbl(t2, t4); - fp3_sub(r->x, r->x, t2); - - /* y3 = R * (V - x3) - 2 * S1 * J. */ - fp3_sub(t4, t4, r->x); - fp3_mul(t4, t4, t0); - fp3_mul(t1, t1, t5); - fp3_dbl(t1, t1); - fp3_sub(r->y, t4, t1); - - /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ - fp3_add(r->z, p->z, q->z); - fp3_sqr(r->z, r->z); - fp3_sub(r->z, r->z, t6); - fp3_mul(r->z, r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); - fp3_free(t2); - fp3_free(t3); - fp3_free(t4); - fp3_free(t5); - fp3_free(t6); - } -#endif -} - -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ /* Public definitions */ @@ -385,7 +136,7 @@ void ep3_add_slp_basic(ep3_t r, fp3_t s, const ep3_t p, const ep3_t q) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep3_add_projc(ep3_t r, const ep3_t p, const ep3_t q) { if (ep3_is_infty(p)) { @@ -398,13 +149,25 @@ void ep3_add_projc(ep3_t r, const ep3_t p, const ep3_t q) { return; } - if (p == q) { - /* TODO: This is a quick hack. Should we fix this? */ - ep3_dbl(r, p); + ep3_add_projc_imp(r, p, q); +} + +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep3_add_jacob(ep3_t r, const ep3_t p, const ep3_t q) { + if (ep3_is_infty(p)) { + ep3_copy(r, q); return; } - ep3_add_projc_imp(r, p, q); + if (ep3_is_infty(q)) { + ep3_copy(r, p); + return; + } + + ep3_add_jacob_imp(r, p, q); } #endif @@ -421,7 +184,6 @@ void ep3_sub(ep3_t r, const ep3_t p, const ep3_t q) { RLC_TRY { ep3_new(t); - ep3_neg(t, q); ep3_add(r, p, t); } diff --git a/src/epx/relic_ep3_cmp.c b/src/epx/relic_ep3_cmp.c index 265a65c98..10078af81 100644 --- a/src/epx/relic_ep3_cmp.c +++ b/src/epx/relic_ep3_cmp.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of utilities for prime elliptic curves over quadratic - * extensions. + * Implementation of utilities for prime elliptic curves over a cubic + * extension field. * * @ingroup epx */ @@ -37,46 +37,68 @@ /*============================================================================*/ int ep3_cmp(const ep3_t p, const ep3_t q) { - ep3_t r, s; - int result = RLC_NE; + ep3_t r, s; + int result = RLC_NE; if (ep3_is_infty(p) && ep3_is_infty(q)) { return RLC_EQ; } - ep3_null(r); - ep3_null(s); + ep3_null(r); + ep3_null(s); - RLC_TRY { - ep3_new(r); - ep3_new(s); + RLC_TRY { + ep3_new(r); + ep3_new(s); - if ((p->coord != BASIC) && (q->coord != BASIC)) { - /* If the two points are not normalized, it is faster to compare - * x1 * z2^2 == x2 * z1^2 and y1 * z2^3 == y2 * z1^3. */ - fp3_sqr(r->z, p->z); - fp3_sqr(s->z, q->z); - fp3_mul(r->x, p->x, s->z); - fp3_mul(s->x, q->x, r->z); - fp3_mul(r->z, r->z, p->z); - fp3_mul(s->z, s->z, q->z); - fp3_mul(r->y, p->y, s->z); - fp3_mul(s->y, q->y, r->z); - } else { - ep3_norm(r, p); - ep3_norm(s, q); - } + switch (q->coord) { + case PROJC: + /* If q is in homogeneous projective coordinates, compute + * x1 * z2 and y1 * z2. */ + fp3_mul(r->x, p->x, q->z); + fp3_mul(r->y, p->y, q->z); + break; + case JACOB: + /* If q is in Jacobian projective coordinates, compute + * x2 * z1^2 and y2 * z1^3. */ + fp3_sqr(r->z, q->z); + fp3_mul(r->x, p->x, r->z); + fp3_mul(r->z, r->z, q->z); + fp3_mul(r->y, p->y, r->z); + break; + default: + ep3_copy(r, p); + break; + } - if ((fp3_cmp(r->x, s->x) == RLC_EQ) && - (fp3_cmp(r->y, s->y) == RLC_EQ)) { - result = RLC_EQ; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - ep3_free(r); - ep3_free(s); - } + switch (p->coord) { + /* Now do the same for the other point. */ + case PROJC: + fp3_mul(s->x, q->x, p->z); + fp3_mul(s->y, q->y, p->z); + break; + case JACOB: + fp3_sqr(s->z, p->z); + fp3_mul(s->x, q->x, s->z); + fp3_mul(s->z, s->z, p->z); + fp3_mul(s->y, q->y, s->z); + break; + default: + ep3_copy(s, q); + break; + } - return result; + if ((fp3_cmp(r->x, s->x) == RLC_EQ) && (fp3_cmp(r->y, s->y) == RLC_EQ)) { + result = RLC_EQ; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep3_free(r); + ep3_free(s); + } + + return result; } diff --git a/src/epx/relic_ep3_curve.c b/src/epx/relic_ep3_curve.c index 8bb97eff3..ff9ba52a1 100644 --- a/src/epx/relic_ep3_curve.c +++ b/src/epx/relic_ep3_curve.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of configuration of prime elliptic curves over quartic - * extensions. + * Implementation of configuration of prime elliptic curves over a cubic + * extension field. * * @ingroup epx */ @@ -241,6 +241,49 @@ int ep3_curve_opt_b(void) { return core_get()->ep3_opt_b; } +void ep3_curve_mul_a(fp3_t c, const fp3_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep3_opt_a) { + case RLC_ZERO: + fp3_zero(c); + break; + case RLC_ONE: + fp3_copy(c, a); + break; + case RLC_TWO: + fp3_dbl(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp3_mul_dig(c, a, ctx->ep3_a[0]); + break; +#endif + default: + fp3_mul(c, a, ctx->ep3_a); + break; + } +} + +void ep3_curve_mul_b(fp3_t c, const fp3_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep3_opt_b) { + case RLC_ZERO: + fp3_zero(c); + break; + case RLC_ONE: + fp3_copy(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp3_mul_dig(c, a, ctx->ep3_b[0]); + break; +#endif + default: + fp3_mul(c, a, ctx->ep3_b); + break; + } +} + int ep3_curve_is_twist(void) { return core_get()->ep3_is_twist; } @@ -249,12 +292,12 @@ void ep3_curve_get_gen(ep3_t g) { ep3_copy(g, core_get()->ep3_g); } -void ep3_curve_get_a(fp3_t a) { - fp3_copy(a, core_get()->ep3_a); +fp_t *ep3_curve_get_a(void) { + return core_get()->ep3_a; } -void ep3_curve_get_b(fp3_t b) { - fp3_copy(b, core_get()->ep3_b); +fp_t *ep3_curve_get_b(void) { + return core_get()->ep3_b; } void ep3_curve_get_ord(bn_t n) { diff --git a/src/epx/relic_ep3_dbl.c b/src/epx/relic_ep3_dbl.c index 27b09b10c..fa4da39b6 100644 --- a/src/epx/relic_ep3_dbl.c +++ b/src/epx/relic_ep3_dbl.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of doubling on elliptic prime curves over quartic - * extensions. + * Implementation of doubling on elliptic prime curves over a cubic extension + * field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_dbl_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -43,201 +44,41 @@ * elliptic curve. * * @param[out] r - the result. - * @param[out] s - the resulting slope. + * @param[out] s - the slope. * @param[in] p - the point to double. */ -static void ep3_dbl_basic_imp(ep3_t r, fp3_t s, const ep3_t p) { - 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 = 1/(2 * y1). */ - fp3_dbl(t0, p->y); - fp3_inv(t0, t0); - - /* t1 = 3 * x1^2 + a. */ - fp3_sqr(t1, p->x); - fp3_copy(t2, t1); - fp3_dbl(t1, t1); - fp3_add(t1, t1, t2); - - ep3_curve_get_a(t2); - fp3_add(t1, t1, t2); - - /* t1 = (3 * x1^2 + a)/(2 * y1). */ - fp3_mul(t1, t1, t0); - - if (s != NULL) { - fp3_copy(s, t1); - } - - /* t2 = t1^2. */ - fp3_sqr(t2, t1); - - /* x3 = t1^2 - 2 * x1. */ - fp3_dbl(t0, p->x); - fp3_sub(t0, t2, t0); - - /* y3 = t1 * (x1 - x3) - y1. */ - fp3_sub(t2, p->x, t0); - fp3_mul(t1, t1, t2); - - fp3_sub(r->y, t1, p->y); - - fp3_copy(r->x, t0); - fp3_copy(r->z, p->z); - - r->coord = BASIC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); - fp3_free(t2); - } -} +TMPL_DBL_BASIC_IMP(ep3, fp3); #endif /* EP_ADD == BASIC */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) /** - * Doubles a point represented in affine coordinates on an ordinary prime + * Doubles a point represented in projective coordinates on an ordinary prime * elliptic curve. * - * @param[out] r - the result. - * @param[in] p - the point to double. + * @param r - the result. + * @param p - the point to double. */ -static void ep3_dbl_projc_imp(ep3_t r, const ep3_t p) { - fp3_t t0, t1, t2, t3, t4, t5; - - fp3_null(t0); - fp3_null(t1); - fp3_null(t2); - fp3_null(t3); - fp3_null(t4); - fp3_null(t5); - - RLC_TRY { - fp3_new(t0); - fp3_new(t1); - fp3_new(t2); - fp3_new(t3); - fp3_new(t4); - fp3_new(t5); - - if (ep_curve_opt_a() == RLC_ZERO) { - fp3_sqr(t0, p->x); - fp3_add(t2, t0, t0); - fp3_add(t0, t2, t0); - - fp3_sqr(t3, p->y); - fp3_mul(t1, t3, p->x); - fp3_add(t1, t1, t1); - fp3_add(t1, t1, t1); - fp3_sqr(r->x, t0); - fp3_add(t2, t1, t1); - fp3_sub(r->x, r->x, t2); - fp3_mul(r->z, p->z, p->y); - fp3_add(r->z, r->z, r->z); - fp3_add(t3, t3, t3); - - fp3_sqr(t3, t3); - fp3_add(t3, t3, t3); - fp3_sub(t1, t1, r->x); - fp3_mul(r->y, t0, t1); - fp3_sub(r->y, r->y, t3); - } else { - /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ - - /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ - fp3_sqr(t0, p->x); - fp3_sqr(t1, p->y); - fp3_sqr(t2, t1); - - if (p->coord != BASIC) { - /* t3 = z1^2. */ - fp3_sqr(t3, p->z); +TMPL_DBL_PROJC_IMP(ep3, fp3); - if (ep_curve_get_a() == RLC_ZERO) { - /* z3 = 2 * y1 * z1. */ - fp3_mul(r->z, p->y, p->z); - fp3_dbl(r->z, r->z); - } else { - /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ - fp3_add(r->z, p->y, p->z); - fp3_sqr(r->z, r->z); - fp3_sub(r->z, r->z, t1); - fp3_sub(r->z, r->z, t3); - } - } else { - /* z3 = 2 * y1. */ - fp3_dbl(r->z, p->y); - } - - /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ - fp3_add(t4, p->x, t1); - fp3_sqr(t4, t4); - fp3_sub(t4, t4, t0); - fp3_sub(t4, t4, t2); - fp3_dbl(t4, t4); - - /* t5 = M = 3 * x1^2 + a * z1^4. */ - fp3_dbl(t5, t0); - fp3_add(t5, t5, t0); - if (p->coord != BASIC) { - fp3_sqr(t3, t3); - ep3_curve_get_a(t1); - fp3_mul(t1, t3, t1); - fp3_add(t5, t5, t1); - } else { - ep3_curve_get_a(t1); - fp3_add(t5, t5, t1); - } - - /* x3 = T = M^2 - 2 * S. */ - fp3_sqr(r->x, t5); - fp3_dbl(t1, t4); - fp3_sub(r->x, r->x, t1); +#endif /* EP_ADD == PROJC */ - /* y3 = M * (S - T) - 8 * y1^4. */ - fp3_dbl(t2, t2); - fp3_dbl(t2, t2); - fp3_dbl(t2, t2); - fp3_sub(t4, t4, r->x); - fp3_mul(t5, t5, t4); - fp3_sub(r->y, t5, t2); - } +#if EP_ADD == JACOB || !defined(STRIP) - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); - fp3_free(t2); - fp3_free(t3); - fp3_free(t4); - fp3_free(t5); - } -} +/** + * Doubles a point represented in Jacobian coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param p - the point to double. + */ +TMPL_DBL_JACOB_IMP(ep3, fp3); -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ - /* Public definitions */ +/* Public definitions */ /*============================================================================*/ #if EP_ADD == BASIC || !defined(STRIP) @@ -247,7 +88,6 @@ void ep3_dbl_basic(ep3_t r, const ep3_t p) { ep3_set_infty(r); return; } - ep3_dbl_basic_imp(r, NULL, p); } @@ -262,7 +102,7 @@ void ep3_dbl_slp_basic(ep3_t r, fp3_t s, const ep3_t p) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep3_dbl_projc(ep3_t r, const ep3_t p) { if (ep3_is_infty(p)) { @@ -274,3 +114,16 @@ void ep3_dbl_projc(ep3_t r, const ep3_t p) { } #endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep3_dbl_jacob(ep3_t r, const ep3_t p) { + if (ep3_is_infty(p)) { + ep3_set_infty(r); + return; + } + + ep3_dbl_jacob_imp(r, p); +} + +#endif diff --git a/src/epx/relic_ep3_frb.c b/src/epx/relic_ep3_frb.c index 1384425f1..ecff8a278 100644 --- a/src/epx/relic_ep3_frb.c +++ b/src/epx/relic_ep3_frb.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of frobenius action on prime elliptic curves over - * quadratic extensions. + * Implementation of frobenius action on prime elliptic curves over a cubic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep3_map.c b/src/epx/relic_ep3_map.c index 8550ea179..29388c842 100644 --- a/src/epx/relic_ep3_map.c +++ b/src/epx/relic_ep3_map.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of hashing to a prime elliptic curve over a quadratic - * extension. + * Implementation of hashing to a prime elliptic curve over a cubic extension + * field. * * @ingroup epx */ @@ -115,29 +115,17 @@ void ep3_map(ep3_t p, const uint8_t *msg, size_t len) { fp3_sqr(z1, z1); fp3_add(z1, z1, u); - ep3_curve_get_b(w); - - fp3_sqr(t, x1); - fp3_mul(t, t, x1); - fp3_add(t, t, w); - - fp3_sqr(u, y1); - fp3_mul(u, u, y1); - fp3_add(u, u, w); - - fp3_sqr(v, z1); - fp3_mul(v, v, z1); - fp3_add(v, v, w); + ep3_rhs(t, x1); + ep3_rhs(u, y1); + ep3_rhs(v, z1); c2 = fp3_is_sqr(u); c3 = fp3_is_sqr(v); - for (int i = 0; i < 3; i++) { - dv_swap_cond(x1[i], y1[i], RLC_FP_DIGS, c2); - dv_swap_cond(t[i], u[i], RLC_FP_DIGS, c2); - dv_swap_cond(x1[i], z1[i], RLC_FP_DIGS, c3); - dv_swap_cond(t[i], v[i], RLC_FP_DIGS, c3); - } + fp3_copy_sec(t, u, c2); + fp3_copy_sec(x1, y1, c2); + fp3_copy_sec(t, v, c3); + fp3_copy_sec(x1, z1, c3); if (!fp3_srt(t, t)) { RLC_THROW(ERR_NO_VALID); @@ -156,9 +144,7 @@ void ep3_map(ep3_t p, const uint8_t *msg, size_t len) { sign ^= (t0 | (t0z & (t1 | (t1z & t2)))); fp3_neg(u, t); - dv_swap_cond(t[0], u[0], RLC_FP_DIGS, sign); - dv_swap_cond(t[1], u[1], RLC_FP_DIGS, sign); - dv_swap_cond(t[2], u[2], RLC_FP_DIGS, sign); + fp3_copy_sec(t, u, sign); fp3_copy(p->x, x1); fp3_copy(p->y, t); diff --git a/src/epx/relic_ep3_mul.c b/src/epx/relic_ep3_mul.c index 4ea09a1ee..a814664fb 100644 --- a/src/epx/relic_ep3_mul.c +++ b/src/epx/relic_ep3_mul.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point multiplication on prime elliptic curves over - * quadratic extensions. + * Implementation of point multiplication on prime elliptic curves over a + * cubic extensions. * * @ingroup epx */ @@ -36,8 +36,6 @@ /* Private definitions */ /*============================================================================*/ -#if EP_MUL == LWNAF || !defined(STRIP) - #if defined(EP_ENDOM) static void ep3_psi(ep3_t r, const ep3_t p) { @@ -85,6 +83,8 @@ static void ep3_psi(ep3_t r, const ep3_t p) { } } +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep3_mul_glv_imp(ep3_t r, const ep3_t p, const bn_t k) { int i, j; size_t l, _l[6]; @@ -165,10 +165,133 @@ static void ep3_mul_glv_imp(ep3_t r, const ep3_t p, const bn_t k) { } } +#endif /* EP_MUL == LWNAF */ + +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep3_mul_reg_gls(ep3_t r, const ep3_t p, const bn_t k) { + int8_t reg[6][RLC_FP_BITS + 1], b[6], s[6], c0, n0; + ep3_t q, w, t[6][1 << (RLC_WIDTH - 2)]; + bn_t n, _k[6], u; + size_t l, len, _l[6]; + + bn_null(n); + bn_null(u); + ep3_null(q); + ep3_null(w); + + RLC_TRY { + bn_new(n); + bn_new(u); + ep3_new(q); + ep3_new(w); + for (size_t i = 0; i < 6; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep3_null(t[i][j]); + ep3_new(t[i][j]); + } + } + + ep3_curve_get_ord(n); + fp_prime_get_par(u); + bn_mod(_k[0], k, n); + bn_rec_frb(_k, 6, _k[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + /* Make some extra room for BN curves that grow subscalars by 1. */ + len = bn_bits(u) + (ep_curve_is_pairf() == EP_BN); + ep3_norm(t[0][0], p); + for (size_t i = 0; i < 6; i++) { + s[i] = bn_sign(_k[i]); + bn_abs(_k[i], _k[i]); + b[i] = bn_is_even(_k[i]); + _k[i]->dp[0] |= b[i]; + + _l[i] = RLC_FP_BITS + 1; + bn_rec_reg(reg[i], &_l[i], _k[i], len, RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + ep3_psi(t[i][0], t[i - 1][0]); + } + } + + for (size_t i = 0; i < 6; i++) { + ep3_neg(q, t[i][0]); + fp3_copy_sec(q->y, t[i][0]->y, s[i] == RLC_POS); + ep3_tab(t[i], q, RLC_WIDTH); + } + +#if defined(EP_MIXED) + fp3_set_dig(w->z, 1); + w->coord = BASIC; +#else + w->coord = = EP_ADD; +#endif + + ep3_set_infty(r); + for (int j = l - 1; j >= 0; j--) { + for (size_t i = 0; i < RLC_WIDTH - 1; i++) { + ep3_dbl(r, r); + } + + for (size_t i = 0; i < 6; i++) { + n0 = reg[i][j]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + + for (size_t m = 0; m < (1 << (RLC_WIDTH - 2)); m++) { + fp3_copy_sec(w->x, t[i][m]->x, m == n0); + fp3_copy_sec(w->y, t[i][m]->y, m == n0); + #if !defined(EP_MIXED) + fp3_copy_sec(w->z, t[i][m]->z, m == n0); + #endif + } + + ep3_neg(q, w); + fp3_copy_sec(q->y, w->y, c0 == 0); + ep3_add(r, r, q); + } + } + + for (size_t i = 0; i < 6; i++) { + /* Tables are built with points already negated, so no need here. */ + ep3_sub(q, r, t[i][0]); + fp3_copy_sec(r->x, q->x, b[i]); + fp3_copy_sec(r->y, q->y, b[i]); + fp3_copy_sec(r->z, q->z, b[i]); + } + + /* Convert r to affine coordinates. */ + ep3_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + ep3_free(q); + ep3_free(w); + for (int i = 0; i < 6; i++) { + bn_free(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep3_free(t[i][j]); + } + } + } +} + +#endif /* EP_MUL == LWREG */ #endif /* EP_ENDOM */ #if defined(EP_PLAIN) || defined(EP_SUPER) +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep3_mul_naf_imp(ep3_t r, const ep3_t p, const bn_t k) { int i, n; int8_t naf[RLC_FP_BITS + 1]; @@ -217,9 +340,95 @@ static void ep3_mul_naf_imp(ep3_t r, const ep3_t p, const bn_t k) { } } -#endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_MUL == LWNAF */ +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep3_mul_reg_imp(ep3_t r, const ep3_t p, const bn_t k) { + bn_t _k; + int8_t s, reg[1 + RLC_CEIL(RLC_FP_BITS + 1, RLC_WIDTH - 1)]; + ep3_t t[1 << (RLC_WIDTH - 2)], u, v; + size_t l, n; + + bn_null(_k); + + RLC_TRY { + bn_new(_k); + ep3_new(u); + ep3_new(v); + /* Prepare the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep3_null(t[i]); + ep3_new(t[i]); + } + /* Compute the precomputation table. */ + ep3_tab(t, p, RLC_WIDTH); + + ep3_curve_get_ord(_k); + n = bn_bits(_k); + + /* Make a copy of the scalar for processing. */ + bn_abs(_k, k); + _k->dp[0] |= 1; + + /* Compute the regular w-NAF representation of k. */ + l = RLC_CEIL(n, RLC_WIDTH - 1) + 1; + bn_rec_reg(reg, &l, _k, n, RLC_WIDTH); + +#if defined(EP_MIXED) + fp3_set_dig(u->z, 1); + u->coord = BASIC; +#else + u->coord = EP_ADD; +#endif + ep3_set_infty(r); + for (int i = l - 1; i >= 0; i--) { + for (size_t j = 0; j < RLC_WIDTH - 1; j++) { + ep3_dbl(r, r); + } + + n = reg[i]; + s = (n >> 7); + n = ((n ^ s) - s) >> 1; + + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + fp3_copy_sec(u->x, t[j]->x, j == n); + fp3_copy_sec(u->y, t[j]->y, j == n); +#if !defined(EP_MIXED) + fp_copy_sec(u->z, t[j]->z, j == n); +#endif + } + ep3_neg(v, u); + fp3_copy_sec(u->y, v->y, s != 0); + ep3_add(r, r, u); + } + /* t[0] has an unmodified copy of p. */ + ep3_sub(u, r, t[0]); + fp3_copy_sec(r->x, u->x, bn_is_even(k)); + fp3_copy_sec(r->y, u->y, bn_is_even(k)); + fp3_copy_sec(r->z, u->z, bn_is_even(k)); + /* Convert r to affine coordinates. */ + ep3_norm(r, r); + ep3_neg(u, r); + fp3_copy_sec(r->y, u->y, bn_sign(k) == RLC_NEG); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep3_free(t[i]); + } + bn_free(_k); + ep3_free(u); + ep3_free(v); + } +} + +#endif /* EP_MUL == LWREG */ +#endif /* EP_PLAIN || EP_SUPER */ + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -383,7 +592,7 @@ void ep3_mul_monty(ep3_t r, const ep3_t p, const bn_t k) { bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); - dv_swap_cond(l->dp, n->dp, RLC_MAX(l->used, n->used), + dv_swap_sec(l->dp, n->dp, RLC_MAX(l->used, n->used), bn_get_bit(l, bits) == 0); l->used = RLC_SEL(l->used, n->used, bn_get_bit(l, bits) == 0); @@ -396,26 +605,26 @@ void ep3_mul_monty(ep3_t r, const ep3_t p, const bn_t k) { for (int i = bits - 1; i >= 0; i--) { int j = bn_get_bit(l, i); - dv_swap_cond(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[2], t[1]->x[2], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[2], t[1]->y[2], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[2], t[1]->z[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[2], t[1]->x[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[2], t[1]->y[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[2], t[1]->z[2], RLC_FP_DIGS, j ^ 1); ep3_add(t[0], t[0], t[1]); ep3_dbl(t[1], t[1]); - dv_swap_cond(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[2], t[1]->x[2], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[2], t[1]->y[2], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[2], t[1]->z[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0], t[1]->x[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1], t[1]->x[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[2], t[1]->x[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0], t[1]->y[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1], t[1]->y[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[2], t[1]->y[2], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0], t[1]->z[0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1], t[1]->z[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[2], t[1]->z[2], RLC_FP_DIGS, j ^ 1); } ep3_norm(r, t[0]); @@ -455,6 +664,28 @@ void ep3_mul_lwnaf(ep3_t r, const ep3_t p, const bn_t k) { #endif +#if EP_MUL == LWREG || !defined(STRIP) + +void ep3_mul_lwreg(ep3_t r, const ep3_t p, const bn_t k) { + if (bn_is_zero(k) || ep3_is_infty(p)) { + ep3_set_infty(r); + return; + } + +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + ep3_mul_reg_gls(r, p, k); + return; + } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + ep3_mul_reg_imp(r, p, k); +#endif +} + +#endif + void ep3_mul_gen(ep3_t r, const bn_t k) { if (bn_is_zero(k)) { ep3_set_infty(r); diff --git a/src/epx/relic_ep3_mul_cof.c b/src/epx/relic_ep3_mul_cof.c index a0deca806..8314a44c7 100644 --- a/src/epx/relic_ep3_mul_cof.c +++ b/src/epx/relic_ep3_mul_cof.c @@ -25,14 +25,13 @@ * @file * * Implementation of point multiplication of a prime elliptic curve over a - * quadratic extension by the curve cofactor. + * cubic extension field by the curve cofactor. * * @ingroup epx */ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Private definitions */ @@ -318,7 +317,7 @@ void ep3_mul_cof(ep3_t r, const ep3_t p) { default: /* Now, multiply by cofactor to get the correct group. */ ep3_curve_get_cof(k); - ep3_mul_basic(r, p, k); + ep3_mul_big(r, p, k); break; } } RLC_CATCH_ANY { diff --git a/src/epx/relic_ep3_mul_fix.c b/src/epx/relic_ep3_mul_fix.c index 66276d5a2..efde195e1 100644 --- a/src/epx/relic_ep3_mul_fix.c +++ b/src/epx/relic_ep3_mul_fix.c @@ -25,7 +25,7 @@ * @file * * Implementation of fixed point multiplication on a prime elliptic curve over - * a quadratic extension. + * a cubic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep3_mul_sim.c b/src/epx/relic_ep3_mul_sim.c index 408232a57..625948fa4 100644 --- a/src/epx/relic_ep3_mul_sim.c +++ b/src/epx/relic_ep3_mul_sim.c @@ -25,7 +25,7 @@ * @file * * Implementation of simultaneous point multiplication on a prime elliptic - * curve over a quartic extension. + * curve over a cubic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep3_neg.c b/src/epx/relic_ep3_neg.c index 1c076cda8..56594da96 100644 --- a/src/epx/relic_ep3_neg.c +++ b/src/epx/relic_ep3_neg.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point negation on elliptic prime curves over quadratic - * extensions. + * Implementation of point negation on elliptic prime curves over a cubic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep3_norm.c b/src/epx/relic_ep3_norm.c index 0015c2711..5f8b853e6 100644 --- a/src/epx/relic_ep3_norm.c +++ b/src/epx/relic_ep3_norm.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point normalization on prime elliptic curves over quadratic - * extensions. + * Implementation of point normalization on prime elliptic curves over a cubic + * extension field. * * @ingroup epx */ @@ -43,36 +43,45 @@ * * @param r - the result. * @param p - the point to normalize. + * @param inv - the flag to indicate if z is already inverted. */ -static void ep3_norm_imp(ep3_t r, const ep3_t p, int inverted) { +static void ep3_norm_imp(ep3_t r, const ep3_t p, int inv) { if (p->coord != BASIC) { - fp3_t t0, t1; + fp3_t t; - fp3_null(t0); - fp3_null(t1); + fp3_null(t); RLC_TRY { + fp3_new(t); - fp3_new(t0); - fp3_new(t1); - - if (inverted) { - fp3_copy(t1, p->z); + if (inv) { + fp3_copy(r->z, p->z); } else { - fp3_inv(t1, p->z); + fp3_inv(r->z, p->z); + } + + switch (p->coord) { + case PROJC: + fp3_mul(r->x, p->x, r->z); + fp3_mul(r->y, p->y, r->z); + break; + case JACOB: + fp3_sqr(t, r->z); + fp3_mul(r->x, p->x, t); + fp3_mul(t, t, r->z); + fp3_mul(r->y, p->y, t); + break; + default: + ep3_copy(r, p); + break; } - fp3_sqr(t0, t1); - fp3_mul(r->x, p->x, t0); - fp3_mul(t0, t0, t1); - fp3_mul(r->y, p->y, t0); fp3_set_dig(r->z, 1); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { - fp3_free(t0); - fp3_free(t1); + fp3_free(t); } } @@ -92,17 +101,18 @@ void ep3_norm(ep3_t r, const ep3_t p) { } if (p->coord == BASIC) { - /* If the point is represented in affine coordinates, we just copy it. */ + /* If the point is represented in affine coordinates, just copy it. */ ep3_copy(r, p); + return; } #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) ep3_norm_imp(r, p, 0); -#endif +#endif /* EP_ADD == PROJC */ } void ep3_norm_sim(ep3_t *r, const ep3_t *t, int n) { int i; - fp3_t *a = RLC_ALLOCA(fp3_t, n); + fp3_t* a = RLC_ALLOCA(fp3_t, n); RLC_TRY { if (a == NULL) { @@ -114,18 +124,20 @@ void ep3_norm_sim(ep3_t *r, const ep3_t *t, int n) { fp3_copy(a[i], t[i]->z); } - fp3_inv_sim(a, a, n); + fp3_inv_sim(a, (const fp3_t *)a, n); for (i = 0; i < n; i++) { fp3_copy(r[i]->x, t[i]->x); fp3_copy(r[i]->y, t[i]->y); - fp3_copy(r[i]->z, a[i]); + if (!ep3_is_infty(t[i])) { + fp3_copy(r[i]->z, a[i]); + } } #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) for (i = 0; i < n; i++) { ep3_norm_imp(r[i], r[i], 1); } -#endif +#endif /* EP_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/epx/relic_ep3_util.c b/src/epx/relic_ep3_util.c index ec7129aeb..a3b9676b2 100644 --- a/src/epx/relic_ep3_util.c +++ b/src/epx/relic_ep3_util.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of comparison for points on prime elliptic curves over - * quartic extensions. + * Implementation of comparison for points on prime elliptic curves over a + * cubic extension field. * * @ingroup epx */ @@ -89,13 +89,18 @@ void ep3_blind(ep3_t r, const ep3_t p) { #if EP_ADD == BASIC (void)rand; ep3_copy(r, p); -#else +#elif EP_ADD == PROJC + fp3_mul(r->x, p->x, rand); + fp3_mul(r->y, p->y, rand); + fp3_mul(r->z, p->z, rand); + r->coord = PROJC; +#elif EP_ADD == JACOB fp3_mul(r->z, p->z, rand); fp3_mul(r->y, p->y, rand); fp3_sqr(rand, rand); fp3_mul(r->x, r->x, rand); fp3_mul(r->y, r->y, rand); - r->coord = EP_ADD; + r->coord = JACOB; #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -104,17 +109,15 @@ void ep3_blind(ep3_t r, const ep3_t p) { } } -void ep3_rhs(fp3_t rhs, const ep3_t p) { - fp3_t t0, t1; +void ep3_rhs(fp3_t rhs, const fp3_t x) { + fp3_t t0; fp3_null(t0); - fp3_null(t1); RLC_TRY { fp3_new(t0); - fp3_new(t1); - fp3_sqr(t0, p->x); /* x1^2 */ + fp3_sqr(t0, x); /* x1^2 */ switch (ep3_curve_opt_a()) { case RLC_ZERO: @@ -130,17 +133,15 @@ void ep3_rhs(fp3_t rhs, const ep3_t p) { fp_add_dig(t0[0], t0[0], 2); break; case RLC_TINY: - ep3_curve_get_a(t1); - fp3_mul_dig(t0, t0, t1[0][0]); + fp3_mul_dig(t0, t0, ep3_curve_get_a()[0][0]); break; #endif default: - ep3_curve_get_a(t1); - fp3_add(t0, t0, t1); + fp3_add(t0, t0, ep3_curve_get_a()); break; } - fp3_mul(t0, t0, p->x); /* x1^3 + a * x */ + fp3_mul(t0, t0, x); /* x1^3 + a * x */ switch (ep3_curve_opt_b()) { case RLC_ZERO: @@ -156,13 +157,11 @@ void ep3_rhs(fp3_t rhs, const ep3_t p) { fp3_add_dig(t0, t0, 2); break; case RLC_TINY: - ep3_curve_get_b(t1); - fp3_mul_dig(t0, t0, t1[0][0]); + fp3_mul_dig(t0, t0, ep3_curve_get_b()[0][0]); break; #endif default: - ep3_curve_get_b(t1); - fp3_add(t0, t0, t1); + fp3_add(t0, t0, ep3_curve_get_b()); break; } @@ -171,11 +170,9 @@ void ep3_rhs(fp3_t rhs, const ep3_t p) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { fp3_free(t0); - fp3_free(t1); } } - int ep3_on_curve(const ep3_t p) { ep3_t t; int r = 0; @@ -187,7 +184,7 @@ int ep3_on_curve(const ep3_t p) { ep3_norm(t, p); - ep3_rhs(t->x, t); + ep3_rhs(t->x, t->x); fp3_sqr(t->y, t->y); r = (fp3_cmp(t->x, t->y) == RLC_EQ) || ep3_is_infty(p); diff --git a/src/epx/relic_ep4_add.c b/src/epx/relic_ep4_add.c index 57fda0cfc..4c9c3ff1e 100644 --- a/src/epx/relic_ep4_add.c +++ b/src/epx/relic_ep4_add.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of addition on prime elliptic curves over quartic - * extensions. + * Implementation of addition on prime elliptic curves over a quartic + * extension field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,312 +43,62 @@ * 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 */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) -#if defined(EP_MIXED) || !defined(STRIP) +/** + * Adds a point represented in homogeneous coordinates to a point represented in + * 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. + */ +TMPL_ADD_PROJC_MIX(ep4, fp4); /** - * Adds a point represented in affine coordinates to a point represented in - * projective coordinates. + * Adds two points represented in homogeneous coordinates on an ordinary prime + * elliptic curve. * - * @param r - the result. - * @param s - the slope. - * @param p - the affine point. - * @param q - the projective point. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep4_add_projc_mix(ep4_t r, const ep4_t p, const ep4_t q) { - fp4_t t0, t1, t2, t3, t4, t5, t6; +TMPL_ADD_PROJC_IMP(ep4, fp4); - fp4_null(t0); - fp4_null(t1); - fp4_null(t2); - fp4_null(t3); - fp4_null(t4); - fp4_null(t5); - fp4_null(t6); +#endif /* EP_ADD == PROJC */ - RLC_TRY { - fp4_new(t0); - fp4_new(t1); - fp4_new(t2); - fp4_new(t3); - fp4_new(t4); - fp4_new(t5); - fp4_new(t6); - - if (p->coord != BASIC) { - /* t0 = z1^2. */ - fp4_sqr(t0, p->z); - - /* t3 = U2 = x2 * z1^2. */ - fp4_mul(t3, q->x, t0); - - /* t1 = S2 = y2 * z1^3. */ - fp4_mul(t1, t0, p->z); - fp4_mul(t1, t1, q->y); - - /* t3 = H = U2 - x1. */ - fp4_sub(t3, t3, p->x); - - /* t1 = R = 2 * (S2 - y1). */ - fp4_sub(t1, t1, p->y); - } else { - /* H = x2 - x1. */ - fp4_sub(t3, q->x, p->x); - - /* t1 = R = 2 * (y2 - y1). */ - fp4_sub(t1, q->y, p->y); - } - - /* t2 = HH = H^2. */ - fp4_sqr(t2, t3); - - /* If E is zero. */ - if (fp4_is_zero(t3)) { - if (fp4_is_zero(t1)) { - /* If I is zero, p = q, should have doubled. */ - ep4_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep4_set_infty(r); - } - } else { - /* t5 = J = H * HH. */ - fp4_mul(t5, t3, t2); - - /* t4 = V = x1 * HH. */ - fp4_mul(t4, p->x, t2); - - /* x3 = R^2 - J - 2 * V. */ - fp4_sqr(r->x, t1); - fp4_sub(r->x, r->x, t5); - fp4_dbl(t6, t4); - fp4_sub(r->x, r->x, t6); - - /* y3 = R * (V - x3) - Y1 * J. */ - fp4_sub(t4, t4, r->x); - fp4_mul(t4, t4, t1); - fp4_mul(t1, p->y, t5); - fp4_sub(r->y, t4, t1); - - if (p->coord != BASIC) { - /* z3 = z1 * H. */ - fp4_mul(r->z, p->z, t3); - } else { - /* z3 = H. */ - fp4_copy(r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); - fp4_free(t2); - fp4_free(t3); - fp4_free(t4); - fp4_free(t5); - fp4_free(t6); - } -} +#if EP_ADD == JACOB || !defined(STRIP) -#endif +/** + * Adds a point represented in Jacobian coordinates to a point represented in + * 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. + */ +TMPL_ADD_JACOB_MIX(ep4, fp4); /** - * Adds two points represented in projective coordinates on an ordinary prime + * Adds two points represented in Jacobian coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep4_add_projc_imp(ep4_t r, const ep4_t p, const ep4_t q) { -#if defined(EP_MIXED) && defined(STRIP) - ep4_add_projc_mix(r, p, q); -#else /* General addition. */ - fp4_t t0, t1, t2, t3, t4, t5, t6; - - fp4_null(t0); - fp4_null(t1); - fp4_null(t2); - fp4_null(t3); - fp4_null(t4); - fp4_null(t5); - fp4_null(t6); +TMPL_ADD_JACOB_IMP(ep4, fp4); - RLC_TRY { - fp4_new(t0); - fp4_new(t1); - fp4_new(t2); - fp4_new(t3); - fp4_new(t4); - fp4_new(t5); - fp4_new(t6); - - if (q->coord == BASIC) { - ep4_add_projc_mix(r, p, q); - } else { - /* t0 = z1^2. */ - fp4_sqr(t0, p->z); - - /* t1 = z2^2. */ - fp4_sqr(t1, q->z); - - /* t2 = U1 = x1 * z2^2. */ - fp4_mul(t2, p->x, t1); - - /* t3 = U2 = x2 * z1^2. */ - fp4_mul(t3, q->x, t0); - - /* t6 = z1^2 + z2^2. */ - fp4_add(t6, t0, t1); - - /* t0 = S2 = y2 * z1^3. */ - fp4_mul(t0, t0, p->z); - fp4_mul(t0, t0, q->y); - - /* t1 = S1 = y1 * z2^3. */ - fp4_mul(t1, t1, q->z); - fp4_mul(t1, t1, p->y); - - /* t3 = H = U2 - U1. */ - fp4_sub(t3, t3, t2); - - /* t0 = R = 2 * (S2 - S1). */ - fp4_sub(t0, t0, t1); - - fp4_dbl(t0, t0); - - /* If E is zero. */ - if (fp4_is_zero(t3)) { - if (fp4_is_zero(t0)) { - /* If I is zero, p = q, should have doubled. */ - ep4_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep4_set_infty(r); - } - } else { - /* t4 = I = (2*H)^2. */ - fp4_dbl(t4, t3); - fp4_sqr(t4, t4); - - /* t5 = J = H * I. */ - fp4_mul(t5, t3, t4); - - /* t4 = V = U1 * I. */ - fp4_mul(t4, t2, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp4_sqr(r->x, t0); - fp4_sub(r->x, r->x, t5); - fp4_dbl(t2, t4); - fp4_sub(r->x, r->x, t2); - - /* y3 = R * (V - x3) - 2 * S1 * J. */ - fp4_sub(t4, t4, r->x); - fp4_mul(t4, t4, t0); - fp4_mul(t1, t1, t5); - fp4_dbl(t1, t1); - fp4_sub(r->y, t4, t1); - - /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ - fp4_add(r->z, p->z, q->z); - fp4_sqr(r->z, r->z); - fp4_sub(r->z, r->z, t6); - fp4_mul(r->z, r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); - fp4_free(t2); - fp4_free(t3); - fp4_free(t4); - fp4_free(t5); - fp4_free(t6); - } -#endif -} - -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ /* Public definitions */ @@ -385,7 +136,7 @@ void ep4_add_slp_basic(ep4_t r, fp4_t s, const ep4_t p, const ep4_t q) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep4_add_projc(ep4_t r, const ep4_t p, const ep4_t q) { if (ep4_is_infty(p)) { @@ -398,13 +149,25 @@ void ep4_add_projc(ep4_t r, const ep4_t p, const ep4_t q) { return; } - if (p == q) { - /* TODO: This is a quick hack. Should we fix this? */ - ep4_dbl(r, p); + ep4_add_projc_imp(r, p, q); +} + +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep4_add_jacob(ep4_t r, const ep4_t p, const ep4_t q) { + if (ep4_is_infty(p)) { + ep4_copy(r, q); return; } - ep4_add_projc_imp(r, p, q); + if (ep4_is_infty(q)) { + ep4_copy(r, p); + return; + } + + ep4_add_jacob_imp(r, p, q); } #endif @@ -421,7 +184,6 @@ void ep4_sub(ep4_t r, const ep4_t p, const ep4_t q) { RLC_TRY { ep4_new(t); - ep4_neg(t, q); ep4_add(r, p, t); } diff --git a/src/epx/relic_ep4_cmp.c b/src/epx/relic_ep4_cmp.c index d98f37a35..9df11b6a1 100644 --- a/src/epx/relic_ep4_cmp.c +++ b/src/epx/relic_ep4_cmp.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of utilities for prime elliptic curves over quadratic - * extensions. + * Implementation of utilities for prime elliptic curves over a quartic + * extension field. * * @ingroup epx */ @@ -37,46 +37,68 @@ /*============================================================================*/ int ep4_cmp(const ep4_t p, const ep4_t q) { - ep4_t r, s; - int result = RLC_NE; + ep4_t r, s; + int result = RLC_NE; if (ep4_is_infty(p) && ep4_is_infty(q)) { return RLC_EQ; } - ep4_null(r); - ep4_null(s); + ep4_null(r); + ep4_null(s); - RLC_TRY { - ep4_new(r); - ep4_new(s); + RLC_TRY { + ep4_new(r); + ep4_new(s); - if ((p->coord != BASIC) && (q->coord != BASIC)) { - /* If the two points are not normalized, it is faster to compare - * x1 * z2^2 == x2 * z1^2 and y1 * z2^3 == y2 * z1^3. */ - fp4_sqr(r->z, p->z); - fp4_sqr(s->z, q->z); - fp4_mul(r->x, p->x, s->z); - fp4_mul(s->x, q->x, r->z); - fp4_mul(r->z, r->z, p->z); - fp4_mul(s->z, s->z, q->z); - fp4_mul(r->y, p->y, s->z); - fp4_mul(s->y, q->y, r->z); - } else { - ep4_norm(r, p); - ep4_norm(s, q); - } + switch (q->coord) { + case PROJC: + /* If q is in homogeneous projective coordinates, compute + * x1 * z2 and y1 * z2. */ + fp4_mul(r->x, p->x, q->z); + fp4_mul(r->y, p->y, q->z); + break; + case JACOB: + /* If q is in Jacobian projective coordinates, compute + * x2 * z1^2 and y2 * z1^3. */ + fp4_sqr(r->z, q->z); + fp4_mul(r->x, p->x, r->z); + fp4_mul(r->z, r->z, q->z); + fp4_mul(r->y, p->y, r->z); + break; + default: + ep4_copy(r, p); + break; + } - if ((fp4_cmp(r->x, s->x) == RLC_EQ) && - (fp4_cmp(r->y, s->y) == RLC_EQ)) { - result = RLC_EQ; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - ep4_free(r); - ep4_free(s); - } + switch (p->coord) { + /* Now do the same for the other point. */ + case PROJC: + fp4_mul(s->x, q->x, p->z); + fp4_mul(s->y, q->y, p->z); + break; + case JACOB: + fp4_sqr(s->z, p->z); + fp4_mul(s->x, q->x, s->z); + fp4_mul(s->z, s->z, p->z); + fp4_mul(s->y, q->y, s->z); + break; + default: + ep4_copy(s, q); + break; + } - return result; + if ((fp4_cmp(r->x, s->x) == RLC_EQ) && (fp4_cmp(r->y, s->y) == RLC_EQ)) { + result = RLC_EQ; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep4_free(r); + ep4_free(s); + } + + return result; } diff --git a/src/epx/relic_ep4_curve.c b/src/epx/relic_ep4_curve.c index cb695d924..21e8a87fe 100644 --- a/src/epx/relic_ep4_curve.c +++ b/src/epx/relic_ep4_curve.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of configuration of prime elliptic curves over quartic - * extensions. + * Implementation of configuration of prime elliptic curves over a quartic + * extension field. * * @ingroup epx */ @@ -130,29 +130,6 @@ /** @} */ #endif -#if defined(EP_ENDOM) && FP_PRIME == 765 -/** @{ */ -#define N16_P765_A0 "0" -#define N16_P765_A1 "0" -#define N16_P765_A2 "1" -#define N16_P765_A3 "0" -#define N16_P765_B0 "0" -#define N16_P765_B1 "0" -#define N16_P765_B2 "0" -#define N16_P765_B3 "0" -#define N16_P765_X0 "004C4A977FFCA75E15AEB9C8B8EAB0CAB30A488EF0424C9658FB8A05E4CA6A1E2997FAD9F0DE053D69751CBA6F49059CB2E0BAC08AA25A575BC1E1468E2E1BD78FB87C2ABCA3C20AB55B8B18F5266CD05FC4B26DFB091FB4A130312132D09614" -#define N16_P765_X1 "0EE552F7143FA01D9919C462036AEC50C76BE752823C49910EF121F05B22494897A213DDF33166C6F8CA16995A83B9526EADE2D74366C349313DD126CC89249F282C1F3715BB690A1AD176F53F6EF6D75873E8A857FC0794F2AE1AE7C12D8F8B" -#define N16_P765_X2 "14A32856133B3D59AC0DC99C3D34D830A7003BF41CED95B126BF0D2BAAB3C92A0E24CAFE5B6030F0FBD29E7CF08F808787A273B171B05C50CD052A3C031288BFBDE6CF4F53270477B12621F35193B5FAD47E6A77B33BD2B9FF9D3687AE6AE48D" -#define N16_P765_X3 "0C478BC2CC455CDE662F112B2C4F9B24A0DA57515A44DD61591E3F3532AA8C640D84CAFADECADAE4D249D1038F3D030E173CFA87C51BF90BF49B1DFAB84B9ACC0ABD72349A3ADAB2BF056EF39AB6101F1D89C6C9D7761BFC9D5E0E050E299138" -#define N16_P765_Y0 "00DEDAE825C143B4DFCB3A8B5F87BA7BADE72AF792AB7DFF198FE234AE16D8B5B45D9B033415FD4B59099DAFEF8A5782AC4D86BCD555AFCBA31111E07E34D1233A59505BEABB6FDEDE470A5182D0B6DDE2E48BE313D445EA0D11062D109382D6" -#define N16_P765_Y1 "0D77B57018036B23B857B823374756FC62C05244E47D5237961304B9B7BFDE3BE874B58B5F7B4805726BB0042CEEFF3FBF76F7EBEA3D36CC1E46BBAF4819F76DB1BFBC05E8577D4E992407C245418170CE03D6DD3A153DCC217F995191749773" -#define N16_P765_Y2 "0ADFD23B22ABAF4C64ECE323D37878D1D437EB77860ABF4EC0C2ADA1054D4BAB06422FF17E3A59FE4AE7B254F2228138A50E819616A6F6F44671CE2FB19962D4687510516A6786E06060560D714FF35C05C7F3B8600E5ADBE796DC7FD331C8C4" -#define N16_P765_Y3 "0E9EA14175A8DAA9C83F5A6C7CCBE6E7CBE534B5AEB9A92B8689F73AF7356EEC955FBE18F6D687561E3D13D781DCB3B90C78392093343E30FE68A5E92A61434F366945C20896A3AD11856AF4B4558791CA9BDE9598734BBE1B33CE618E809982" -#define N16_P765_R "9965D956A0DBC8AF273C0100000000000000000000000000000000000000000000000000000000000000000000000001" -#define N16_P765_H "719C0F18991838D271B16518B194F6F145242127E49DC9A094D6CB692E28DC5F17FFA92321BB6498A829BA8C587373ED1198514FA52F945FEF0BD7DB7AEECF44BA1DC59375BEFBFC8467B4B2DCB8BC87E9FBD6615875E2CDA99813230882AE3B19CC78906339C451CE982DED4C8C2B44D01B86D2440D89A5F5AC3BF04E1393A4DC6712246A0E6F966D734F449D38655E7BF22CC56C0609840678EB8285D561CE1E65F73F1142F3C526CA2E28484D72F0B0492E78604F0AAB2DBBD13A082DFB9513D5C0D5C6CCFD13A6D3DA2EEC9A2AEFD40EC51A940F59D64F45BADB3EBEB96FCDAE11951717C5DF0125F274306A90C0FCF19D34FCB0D37683A2743F8C3ECAFE55863AA6B35BD14C7A894E6D7DC05D12E0D551AE0E46AB11D80610EA749AAEA445FE78651B64091AB67E32F33AA4CE905E2AF4A64A03B25A5C08233C52CBB94BF8000E13C04000003C08000000002" -/** @} */ -#endif - #if defined(EP_ENDOM) && FP_PRIME == 765 /** @{ */ #define FM16_P765_A0 "0" @@ -209,16 +186,16 @@ #define N16_P766_B1 "0" #define N16_P766_B2 "0" #define N16_P766_B3 "0" -#define N16_P766_X0 "2DD92375B2A68D713D1D997683DA3E93B0C1713870A6759B37076504F22AFEC776AA9986FFE48F5507793DB266C9C563D26B64423B653977CC9D7A3EA67D52CF708A55E0110E1F21E4676EEC13FF37228D05B74FC124AC6F15931F84039FFF5B" -#define N16_P766_X1 "3BFCCB56ED55A4FBC07136D3577EA5DC5D1ED55079EA0CD7FA75F945D616AF8957935ABF77D532AE66E568CE090109867C58114CD9AE9CCF220BAE9B22148BBEF77A0AF557527A4F87D36CD84DD481FCF78ED87C388E0D4777456B0DF240898E" -#define N16_P766_X2 "1B9DAFE0399513AE63149C5BD87F531A00A9BA81BB42FE35C499BBAD9B985EDDDB94EEEAF944C21B6E36B25768CB3A6EB5EAD839BDEB05E1F86819BCAFD5EB0EF82EFC64D62223CD23ED960D645D213D8B2DE094FE2F78F0C34AFC09EBD39B65" -#define N16_P766_X3 "B22A088D63FC479596ED186B382DECBB180CC51CD5615F1CE9D600B4BCD81DCAFB9369A86E261767B75C2CE12BD4AE372311F8E9E328BA006D52021D1F09DC51B853C3365FCD61B4DA1BD24AB504CE63E11EB4FB0C2FA56704E009A7D1B1944" -#define N16_P766_Y0 "2AB5268BD543054A99076F5DD83E2D8947CC9DBBCCB125C29D791386412830E074378F94D1CC70891ADDF24CE9398490D3F27FBA8EE7F6CB2D71DFE01112BBD0B9B21FE566393AC278562B4390F0673762FB29A6540186B515A0AB9DB96E848C" -#define N16_P766_Y1 "36962D909FC17BD54162AD530987217464D81007D2B07CEBFEDD9E7ACAC7423242132E11169B1F49A9DCDD3EA9EFF0A24CE7AA7A68BFADFD3E07B0517D47F097AB0F9568B54E8AAE190A2D53D430D1118570C0B5EB878364BA9900A44D97505B" -#define N16_P766_Y2 "2B259E06C780DA39E283C221C392A9EE03ACE066967A30A5A4ADEE49E2ECA40DCAAD4CD234FABAA4CFAB20105EE1BEE54403CC17D5BE544B926A699495A5923C6EC7575A64EE412BFAF4C67E4C449F28814D26C4B8F85947EABF97E3818A3097" -#define N16_P766_Y3 "1495AA76C3DA6431BF12D17B346AEDF5EFE50F4F7135F2618075887884DDA700FCC2918462DDE2CF728034461ECCB4C1F76892A809192939D069D3BA3A06D7F7FD94C1E08D74261C847C3E6DCD36B8D93B87D8277EC23300619530B5A5584B8C" -#define N16_P766_R "FFFFFF8401001A46937D417AB554F4F3438C3F42C66CBA08998426591ED55EBA6A16CB364728D491BC20010000000001" -#define N16_P766_H "FFFFFC9C0705A529AA711C4917897B571AB9D0963B7F885C31C06824D3F2584BA226785992D5E850AA5C0B13502F293A1681AF78BC665FEB126F7C4BA70D01AE2CE52E02140F5C16C4AF3B3A49E6351F191B54245F28C8C4C335ECA923DBF5FF15EBDFF8D29E3B70B027074B50A2AF3622E60B09A63B11B30F61AD59875B59751803A75D55EF5123CED27A3E7F29D20CD2617F6532FDCB87592DF3A6720415EB7871CE9D858844438E66F90066DB58804FB9F54832AEEC21CBACEB00A49D6D5AE806679C4AC7DAD3DBD527E4D81095E256780325B815449FA6C11EF0D70D8AEE93923245E95D8CE60384D06F98BC9AC3D2E91CD725371F495C8B2D1E5161377E801D7732A37179669E91008D8152B75C19324815BD89CCB54EC01212F5B906604C08A55DB203EA6049568FFAA1B88B74657771B64387FF992C5CB64A9E758DEC94FE63AB50F5B88140B2AC32248382" +#define N16_P766_X0 "36097A5BDF2276730FCAC23EA21B0C85D46B013D5A33B2D403BD82155F681BC3A1213F7AD40BFD5B64409C6B909A44F1AC391DE4222B56C55CC74DCB5DCEC23696575F80C402A1256C267F9D1CA325558C3357B116AC85CF856E51590FE7C34F" +#define N16_P766_X1 "17CC3006229289EEC6AAA00FD81F17F26CECDE216E03B5DF64B61FEBA6DFF9D3F032642D66F8E5D4DE44934FB1CB99AFB0A6A939ADAFDA1E6197A474C3BBDDBA71E6120B3AAFE1007A8D0F360651B316312F902B1EB346DD2B276FEEE75ABDD1" +#define N16_P766_X2 "2B79EC9BDF7F80A86DD7F3CE18A3D1FAAEAEDE9312797735EA7F090760B4730CEE401EF9CAB0978C14E967FCE1CEEF5660DFA40F367F698D0CDE9C0F0EF361D70E186EA991CD0F6DB63FE88C45EC5909DFC866862C7B1D1DE6A04843761E5E3" +#define N16_P766_X3 "2005908CF374B24B1C7CF8C5CE656D04515082E61F3088C28D58B9E0249CA864AF1773F479D3272C567311FB287E579547743E8CA51A9D4B45FF5D3D6B4A2BB1865B6E4FB045953D716C68A73095A74CCDDAD5AFCEA74E676D37452916B5CB24" +#define N16_P766_Y0 "137A898DDF4399F2ABB29920707790495F645B373F419C4E2A96DA05B90488BED334F2B8A44AF71C92D947009618358A14F8DE18F0D777F0DE4F98625C4024DBEB8EA858A7AEFAEC093EA12ED7A7C70142AE3583D27982B26AFD75FB441A4B66" +#define N16_P766_Y1 "4D0ADEC5B4B77DFBEB78227FC664F7520A469DBEA674C845F64B537ABFB808F9857EEFBDE088D0422C919ECD562D7C668A42F6C2DAB0B26D7C4D4C3B835CBEA2A843CD3A449B44F0D6D4026512670C3600B02CEFDF9BBF21975B596DD732C13" +#define N16_P766_Y2 "2FCE7D8564D037E95317C3110542BB780D8824436B6F3626C8A4BF1D1C1FB7C1FDF12E7BC52D9F19914404EF71873EFB36C95AF0C6635329D556431A902BA01186D968C0D4BF55F17F7FED3072D77D9DE8D151135952C6EE7855E8F6176B4D66" +#define N16_P766_Y3 "2BAD268ACF32E9D617EC80588A3F1063C5565008B9DF82E8E9B8451F874C36157A280057EF467E0BFCA1FE7AF5C79CDCD055011B2F0F14764B8F1C97BEA256BD5A40FC8020486507E52413A11B70F8D6A3ACF396D5F0D8902950A3E3821B4C64" +#define N16_P766_R "FFFF7000238FFAF4807374994CF93FE6E28D406881B18D350193FE6E3E533E4073749FEBD2000238FFFFDC0000010001" +#define N16_P766_H "FFFC10079DE659DE808DDCE130F752738172840B38A5FC5FC7E040BFD9DCEE27BC5A7B95CED5C4229B3FA11F8F6FAE01BE1FBBBAF34CEF81E7CAFC72FAA4ECB8710AB4E1097D5F96BC6E8A5A88DE77C8B1F025B2691EEE839B4DBE2AC3433AA9E3567E22C5F26F401F6D0458C5F931050EB64B76A27B1D74E69AF8751AB329F9AA6F80C46E4F46D6727D476002C6DD1893DDC185AE4BE7842818B8DF91045FAF7F0A85549CFF3D6F3F45C0010E9F70243663C0840EEE489118422163CFDA9A843ABA6C408D3EC6C858FEDF4BDE93A28C7FD16B34CC1E1074ADB78D9F4F7F5E96DC4F0C5DCA4F360BCB4933A50ABAC5204B89055875059167BA03E0402A1CB965B48313B481483B26F3F1192C673BC76FBDA8395741062530251758B6B86500570F6C3FAF490A5C01D1B62653C6C1DF188A9358877DC50DAB36655B01F092A8AF90F6259FB91E5D57E2DA8FDD5F06A2" /** @} */ #endif @@ -358,6 +335,67 @@ int ep4_curve_opt_b(void) { return core_get()->ep4_opt_b; } +void ep4_curve_mul_a(fp4_t c, const fp4_t a) { + ctx_t *ctx = core_get(); + if (ep4_curve_is_twist() == RLC_EP_MTYPE) { + switch (ctx->ep_opt_a) { + case RLC_ZERO: + fp4_zero(c); + break; + case RLC_ONE: + fp4_copy(c, a); + break; + case RLC_TWO: + fp4_dbl(c, a); + break; + default: + fp4_mul(c, a, ctx->ep4_a); + break; + } + fp4_mul_art(c, c); + } else { + switch (ctx->ep8_opt_a) { + case RLC_ZERO: + fp4_zero(c); + break; + case RLC_ONE: + fp4_copy(c, a); + break; + case RLC_TWO: + fp4_dbl(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp4_mul_dig(c, a, ctx->ep4_a[0]); + break; +#endif + default: + fp4_mul(c, a, ctx->ep4_a); + break; + } + } +} + +void ep4_curve_mul_b(fp4_t c, const fp4_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep4_opt_b) { + case RLC_ZERO: + fp4_zero(c); + break; + case RLC_ONE: + fp4_copy(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp4_mul_dig(c, a, ctx->ep4_b[0]); + break; +#endif + default: + fp4_mul(c, a, ctx->ep4_b); + break; + } +} + int ep4_curve_is_twist(void) { return core_get()->ep4_is_twist; } @@ -366,12 +404,12 @@ void ep4_curve_get_gen(ep4_t g) { ep4_copy(g, core_get()->ep4_g); } -void ep4_curve_get_a(fp4_t a) { - fp4_copy(a, core_get()->ep4_a); +fp2_t *ep4_curve_get_a(void) { + return core_get()->ep4_a; } -void ep4_curve_get_b(fp4_t b) { - fp4_copy(b, core_get()->ep4_b); +fp2_t *ep4_curve_get_b(void) { + return core_get()->ep4_b; } void ep4_curve_get_ord(bn_t n) { @@ -444,9 +482,6 @@ void ep4_curve_set_twist(int type) { ASSIGN(B24_P509); break; #elif FP_PRIME == 765 - case N16_P765: - ASSIGN(N16_P765); - break; case FM16_P765: ASSIGN(FM16_P765); break; diff --git a/src/epx/relic_ep4_dbl.c b/src/epx/relic_ep4_dbl.c index 6aa82b9e9..d3978bba1 100644 --- a/src/epx/relic_ep4_dbl.c +++ b/src/epx/relic_ep4_dbl.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of doubling on elliptic prime curves over quartic - * extensions. + * Implementation of doubling on elliptic prime curves over a quartic extension + * field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_dbl_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -43,201 +44,41 @@ * elliptic curve. * * @param[out] r - the result. - * @param[out] s - the resulting slope. + * @param[out] s - the slope. * @param[in] p - the point to double. */ -static void ep4_dbl_basic_imp(ep4_t r, fp4_t s, const ep4_t p) { - 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 = 1/(2 * y1). */ - fp4_dbl(t0, p->y); - fp4_inv(t0, t0); - - /* t1 = 3 * x1^2 + a. */ - fp4_sqr(t1, p->x); - fp4_copy(t2, t1); - fp4_dbl(t1, t1); - fp4_add(t1, t1, t2); - - ep4_curve_get_a(t2); - fp4_add(t1, t1, t2); - - /* t1 = (3 * x1^2 + a)/(2 * y1). */ - fp4_mul(t1, t1, t0); - - if (s != NULL) { - fp4_copy(s, t1); - } - - /* t2 = t1^2. */ - fp4_sqr(t2, t1); - - /* x3 = t1^2 - 2 * x1. */ - fp4_dbl(t0, p->x); - fp4_sub(t0, t2, t0); - - /* y3 = t1 * (x1 - x3) - y1. */ - fp4_sub(t2, p->x, t0); - fp4_mul(t1, t1, t2); - - fp4_sub(r->y, t1, p->y); - - fp4_copy(r->x, t0); - fp4_copy(r->z, p->z); - - r->coord = BASIC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); - fp4_free(t2); - } -} +TMPL_DBL_BASIC_IMP(ep4, fp4); #endif /* EP_ADD == BASIC */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) /** - * Doubles a point represented in affine coordinates on an ordinary prime + * Doubles a point represented in projective coordinates on an ordinary prime * elliptic curve. * - * @param[out] r - the result. - * @param[in] p - the point to double. + * @param r - the result. + * @param p - the point to double. */ -static void ep4_dbl_projc_imp(ep4_t r, const ep4_t p) { - fp4_t t0, t1, t2, t3, t4, t5; - - fp4_null(t0); - fp4_null(t1); - fp4_null(t2); - fp4_null(t3); - fp4_null(t4); - fp4_null(t5); - - RLC_TRY { - fp4_new(t0); - fp4_new(t1); - fp4_new(t2); - fp4_new(t3); - fp4_new(t4); - fp4_new(t5); - - if (ep_curve_opt_a() == RLC_ZERO) { - fp4_sqr(t0, p->x); - fp4_add(t2, t0, t0); - fp4_add(t0, t2, t0); - - fp4_sqr(t3, p->y); - fp4_mul(t1, t3, p->x); - fp4_add(t1, t1, t1); - fp4_add(t1, t1, t1); - fp4_sqr(r->x, t0); - fp4_add(t2, t1, t1); - fp4_sub(r->x, r->x, t2); - fp4_mul(r->z, p->z, p->y); - fp4_add(r->z, r->z, r->z); - fp4_add(t3, t3, t3); - - fp4_sqr(t3, t3); - fp4_add(t3, t3, t3); - fp4_sub(t1, t1, r->x); - fp4_mul(r->y, t0, t1); - fp4_sub(r->y, r->y, t3); - } else { - /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ - - /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ - fp4_sqr(t0, p->x); - fp4_sqr(t1, p->y); - fp4_sqr(t2, t1); - - if (p->coord != BASIC) { - /* t3 = z1^2. */ - fp4_sqr(t3, p->z); +TMPL_DBL_PROJC_IMP(ep4, fp4); - if (ep_curve_get_a() == RLC_ZERO) { - /* z3 = 2 * y1 * z1. */ - fp4_mul(r->z, p->y, p->z); - fp4_dbl(r->z, r->z); - } else { - /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ - fp4_add(r->z, p->y, p->z); - fp4_sqr(r->z, r->z); - fp4_sub(r->z, r->z, t1); - fp4_sub(r->z, r->z, t3); - } - } else { - /* z3 = 2 * y1. */ - fp4_dbl(r->z, p->y); - } - - /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ - fp4_add(t4, p->x, t1); - fp4_sqr(t4, t4); - fp4_sub(t4, t4, t0); - fp4_sub(t4, t4, t2); - fp4_dbl(t4, t4); - - /* t5 = M = 3 * x1^2 + a * z1^4. */ - fp4_dbl(t5, t0); - fp4_add(t5, t5, t0); - if (p->coord != BASIC) { - fp4_sqr(t3, t3); - ep4_curve_get_a(t1); - fp4_mul(t1, t3, t1); - fp4_add(t5, t5, t1); - } else { - ep4_curve_get_a(t1); - fp4_add(t5, t5, t1); - } - - /* x3 = T = M^2 - 2 * S. */ - fp4_sqr(r->x, t5); - fp4_dbl(t1, t4); - fp4_sub(r->x, r->x, t1); +#endif /* EP_ADD == PROJC */ - /* y3 = M * (S - T) - 8 * y1^4. */ - fp4_dbl(t2, t2); - fp4_dbl(t2, t2); - fp4_dbl(t2, t2); - fp4_sub(t4, t4, r->x); - fp4_mul(t5, t5, t4); - fp4_sub(r->y, t5, t2); - } +#if EP_ADD == JACOB || !defined(STRIP) - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); - fp4_free(t2); - fp4_free(t3); - fp4_free(t4); - fp4_free(t5); - } -} +/** + * Doubles a point represented in Jacobian coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param p - the point to double. + */ +TMPL_DBL_JACOB_IMP(ep4, fp4); -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ - /* Public definitions */ +/* Public definitions */ /*============================================================================*/ #if EP_ADD == BASIC || !defined(STRIP) @@ -247,7 +88,6 @@ void ep4_dbl_basic(ep4_t r, const ep4_t p) { ep4_set_infty(r); return; } - ep4_dbl_basic_imp(r, NULL, p); } @@ -262,7 +102,7 @@ void ep4_dbl_slp_basic(ep4_t r, fp4_t s, const ep4_t p) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep4_dbl_projc(ep4_t r, const ep4_t p) { if (ep4_is_infty(p)) { @@ -274,3 +114,16 @@ void ep4_dbl_projc(ep4_t r, const ep4_t p) { } #endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep4_dbl_jacob(ep4_t r, const ep4_t p) { + if (ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + + ep4_dbl_jacob_imp(r, p); +} + +#endif diff --git a/src/epx/relic_ep4_frb.c b/src/epx/relic_ep4_frb.c index 0cea9557d..601aef677 100644 --- a/src/epx/relic_ep4_frb.c +++ b/src/epx/relic_ep4_frb.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of frobenius action on prime elliptic curves over - * quartic extensions. + * Implementation of frobenius action on prime elliptic curves over a quartic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep4_map.c b/src/epx/relic_ep4_map.c index 24a9cfab0..7c47ffe00 100644 --- a/src/epx/relic_ep4_map.c +++ b/src/epx/relic_ep4_map.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of hashing to a prime elliptic curve over a quadratic - * extension. + * Implementation of hashing to a prime elliptic curve over a quartic extension + * field. * * @ingroup epx */ @@ -41,13 +41,15 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len) { /* enough space for two field elements plus extra bytes for uniformity */ const size_t elm = (FP_PRIME + ep_param_level() + 7) / 8; uint8_t t0z, t0, t1, s[2], sign, *h = RLC_ALLOCA(uint8_t, 8 * elm + 1); - fp4_t a, c, t, u, v, w, y, x1, y1, z1; + fp4_t a, b, c, d, t, u, v, w, y, x1, y1, z1, den[3]; ctx_t *ctx = core_get(); bn_t k; bn_null(k); fp4_null(a); + fp4_null(b); fp4_null(c); + fp4_null(d); fp4_null(t); fp4_null(u); fp4_null(v); @@ -56,11 +58,16 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len) { fp4_null(x1); fp4_null(y1); fp4_null(z1); + fp4_null(den[0]); + fp4_null(den[1]); + fp4_null(den[2]); RLC_TRY { bn_new(k); fp4_new(a); + fp4_new(b); fp4_new(c); + fp4_new(d); fp4_new(t); fp4_new(u); fp4_new(v); @@ -69,214 +76,205 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len) { fp4_new(x1); fp4_new(y1); fp4_new(z1); + fp4_new(den[0]); + fp4_new(den[1]); + fp4_new(den[2]); - if (ep4_curve_opt_b() == RLC_ZERO) { - /* This is the approach due to Koshelev introduced in - * https://eprint.iacr.org/2021/1034.pdf */ - - md_xmd(h, 4 * elm + 1, msg, len, (const uint8_t *)"RELIC", 5); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - bn_read_bin(k, h, elm); - fp_prime_conv(u[i][j], k); - h += elm; - } + md_xmd(h, 8 * elm + 1, msg, len, (const uint8_t *)"RELIC", 5); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + bn_read_bin(k, h, elm); + fp_prime_conv(u[i][j], k); + h += elm; + bn_read_bin(k, h, elm); + fp_prime_conv(t[i][j], k); + h += elm; } - h -= 4*elm; - - /* Compute c = 3*a^2, t^2 = 6a(9u^5 − 14au^3 + 3cu).*/ - ep4_curve_get_a(a); - fp4_neg(a, a); - fp4_sqr(c, a); - fp4_dbl(t, c); - fp4_add(c, c, t); - fp4_dbl(t, c); - fp4_add(t, t, c); - fp4_mul(t, t, u); - - fp4_sqr(v, u); - fp4_mul(w, v, u); - fp4_mul(x1, w, a); - fp4_mul_dig(x1, x1, 14); - fp4_sub(t, t, x1); - - fp4_mul(w, w, v); - fp4_dbl(x1, w); - fp4_add(w, w, x1); - fp4_dbl(x1, w); - fp4_add(w, w, x1); - fp4_add(t, t, w); - fp4_mul(t, t, a); - fp4_dbl(t, t); - fp4_dbl(x1, t); - fp4_add(t, t, x1); - dig_t c1 = fp4_is_sqr(t); - /* If t is not square, compute u = a/u, t = a*sqrt(a*t)/u^3*/ - fp4_inv(x1, u); - fp4_mul(y1, t, a); - /* If t is a square, extract its square root. */ - dv_copy_cond(t[0][0], y1[0][0], RLC_FP_DIGS, !c1); - dv_copy_cond(t[0][1], y1[0][1], RLC_FP_DIGS, !c1); - dv_copy_cond(t[1][0], y1[1][0], RLC_FP_DIGS, !c1); - dv_copy_cond(t[1][1], y1[1][1], RLC_FP_DIGS, !c1); - fp4_srt(t, t); - fp4_mul(y1, t, a); - fp4_sqr(y, x1); - fp4_mul(y, y, x1); - fp4_mul(y1, y1, y); - fp4_mul(x1, x1, a); - dv_copy_cond(u[0][0], x1[0][0], RLC_FP_DIGS, !c1); - dv_copy_cond(u[0][1], x1[0][1], RLC_FP_DIGS, !c1); - dv_copy_cond(u[1][0], x1[1][0], RLC_FP_DIGS, !c1); - dv_copy_cond(u[1][1], x1[1][1], RLC_FP_DIGS, !c1); - dv_copy_cond(t[0][0], y1[0][0], RLC_FP_DIGS, !c1); - dv_copy_cond(t[0][1], y1[0][1], RLC_FP_DIGS, !c1); - dv_copy_cond(t[1][0], y1[1][0], RLC_FP_DIGS, !c1); - dv_copy_cond(t[1][1], y1[1][1], RLC_FP_DIGS, !c1); - - /* Compute x = 2^4*i*3*a^2*u / (3*(3*u^2 - a))^2. */ - fp4_zero(y); - fp_copy(y[0][0], ctx->ep_map_c[6]); - fp4_mul(c, c, u); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - fp_mul(x1[i][j], c[i][j], y[0][0]); - } - } - fp4_dbl(x1, x1); - fp4_dbl(x1, x1); - fp4_dbl(x1, x1); - fp4_dbl(p->x, x1); - fp4_sqr(v, u); - fp4_dbl(z1, v); - fp4_add(z1, z1, v); - fp4_sub(z1, z1, a); - fp4_dbl(p->z, z1); - fp4_add(p->z, p->z, z1); + } + sign = h[0] & 1; + h -= 8*elm; - /* Compute y = 3*2*(i-1)*a*(3^2*u^2 + a)*t / (3*(3*u^2 - a))^3. */ - fp_sub_dig(y[0][0], y[0][0], 1); - fp4_mul(y1, y, a); - fp4_dbl(y1, y1); - fp4_dbl(p->y, y1); - fp4_add(p->y, p->y, y1); - fp4_mul(p->y, p->y, t); - fp4_dbl(y1, v); - fp4_add(y1, y1, v); - fp4_dbl(v, y1); - fp4_add(y1, y1, v); - fp4_add(y1, y1, a); - fp4_mul(p->y, p->y, y1); + if (ep_curve_opt_b() == RLC_ZERO) { + fp4_sqr(a, u); + fp4_sqr(b, a); + fp4_mul(c, b, a); + fp4_dbl(p->y, ep4_curve_get_a()); + fp4_dbl(p->y, p->y); + fp4_sqr(p->z, p->y); + fp4_mul(p->z, p->z, p->y); + fp4_add(c, c, p->z); + fp4_sqr(d, t); - /* Multiply by cofactor. */ - p->coord = JACOB; - ep4_norm(p, p); - } + fp4_mul(v, a, d); + fp4_mul(v, v, u); + fp4_mul_dig(v, v, 24); + fp_mul(v[0][0], v[0][0], core_get()->ep_map_c[4]); + fp_mul(v[0][1], v[0][1], core_get()->ep_map_c[4]); + fp_mul(v[1][0], v[1][0], core_get()->ep_map_c[4]); + fp_mul(v[1][1], v[1][1], core_get()->ep_map_c[4]); - if (ep_curve_opt_a() == RLC_ZERO) { - md_xmd(h, 8 * elm + 1, msg, len, (const uint8_t *)"RELIC", 5); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - bn_read_bin(k, h, elm); - fp_prime_conv(u[i][j], k); - h += elm; - bn_read_bin(k, h, elm); - fp_prime_conv(t[i][j], k); - h += elm; - } - } - sign = h[0] & 1; - h -= 8*elm; + fp4_zero(p->x); + fp_sub_dig(p->x[0][0], core_get()->ep_map_c[4], 1); + fp_hlv(p->x[0][0], p->x[0][0]); - fp4_sqr(x1, u); - fp4_mul(x1, x1, u); - fp4_sqr(y1, t); - fp4_add(x1, x1, ctx->ep4_b); - fp4_sub(x1, x1, y1); - fp4_dbl(y1, y1); - fp4_add(y1, y1, x1); - fp4_copy(z1, u); - fp_mul(z1[0][0], z1[0][0], ctx->ep_map_c[4]); - fp_mul(z1[0][1], z1[0][1], ctx->ep_map_c[4]); - fp_mul(z1[1][0], z1[1][0], ctx->ep_map_c[4]); - fp_mul(z1[1][1], z1[1][1], ctx->ep_map_c[4]); - fp4_mul(x1, x1, z1); - fp4_mul(z1, z1, t); - fp4_dbl(z1, z1); + fp4_sqr(w, b); + fp4_mul(y, v, a); + fp4_mul(t, p->y, c); + fp4_add(y, y, t); + fp_mul(y[0][0], y[0][0], p->x[0][0]); + fp_mul(y[0][1], y[0][1], p->x[0][0]); + fp_mul(y[1][0], y[1][0], p->x[0][0]); + fp_mul(y[1][1], y[1][1], p->x[0][0]); - fp4_dbl(y, y1); - fp4_sqr(y, y); - fp4_mul(v, y1, u); - fp4_sub(v, x1, v); - fp4_mul(v, v, z1); - fp4_mul(w, y1, z1); - fp4_dbl(w, w); + fp4_add(den[0], c, v); + fp4_mul(den[0], den[0], u); + fp_mul(den[0][0][0], den[0][0][0], core_get()->ep_map_c[4]); + fp_mul(den[0][0][1], den[0][0][1], core_get()->ep_map_c[4]); + fp_mul(den[0][1][0], den[0][1][0], core_get()->ep_map_c[4]); + fp_mul(den[0][1][1], den[0][1][1], core_get()->ep_map_c[4]); + fp4_mul(den[0], den[0], p->x); + fp4_dbl(den[0], den[0]); + fp4_neg(den[0], den[0]); + fp4_mul(den[1], den[0], p->x); + fp4_sub(den[2], a, p->y); + fp4_sqr(den[2], den[2]); + fp4_mul_dig(den[2], den[2], 216); + fp4_dbl(den[2], den[2]); + fp4_neg(den[2], den[2]); + fp4_mul(den[2], den[2], b); + fp4_mul(den[2], den[2], d); - if (fp4_is_zero(w)) { + if (fp4_is_zero(den[0]) || fp4_is_zero(den[1]) || fp4_is_zero(den[2])) { ep4_set_infty(p); } else { - fp4_inv(w, w); - fp4_mul(x1, v, w); - fp4_add(y1, u, x1); - fp4_neg(y1, y1); - fp4_mul(z1, y, w); - fp4_sqr(z1, z1); - fp4_add(z1, z1, u); - - ep4_curve_get_b(w); + fp4_inv_sim(den, den, 3); + fp4_mul(t, a, p->z); + fp4_mul(y1, p->y, v); + fp4_add(y1, y1, t); + fp4_add(y1, y1, w); + fp_mul(z1[0][0], y[0][0], p->x[0][0]); + fp_mul(z1[0][1], y[0][1], p->x[0][0]); + fp_mul(z1[1][0], y[1][0], p->x[0][0]); + fp_mul(z1[1][1], y[1][1], p->x[0][0]); + fp4_add(x1, y1, z1); + fp4_add(y1, y1, y); + fp4_mul(z1, a, p->y); + fp4_add(z1, z1, b); + fp4_mul(z1, z1, p->y); + fp4_dbl(p->x, z1); + fp4_add(z1, z1, p->x); + fp4_add(z1, z1, v); + fp4_sub(z1, c, z1); + fp4_mul(z1, z1, v); + fp4_sqr(p->z, p->z); + fp4_sub(z1, p->z, z1); + fp4_add(w, w, t); + fp4_add(w, w, t); + fp4_mul(w, w, b); + fp4_add(z1, z1, w); - fp4_sqr(t, x1); - fp4_mul(t, t, x1); - fp4_add(t, t, w); + fp4_mul(x1, x1, den[0]); + fp4_mul(y1, y1, den[1]); + fp4_mul(z1, z1, den[2]); + + ep4_rhs(t, x1); + ep4_rhs(u, y1); + ep4_rhs(v, z1); - fp4_sqr(u, y1); - fp4_mul(u, u, y1); - fp4_add(u, u, w); - - fp4_sqr(v, z1); - fp4_mul(v, v, z1); - fp4_add(v, v, w); + int c2 = fp4_is_sqr(u); + int c3 = fp4_is_sqr(v); - dig_t c2 = fp4_is_sqr(u); - dig_t c3 = fp4_is_sqr(v); - - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - dv_swap_cond(x1[i][j], y1[i][j], RLC_FP_DIGS, c2); - dv_swap_cond(t[i][j], u[i][j], RLC_FP_DIGS, c2); - dv_swap_cond(x1[i][j], z1[i][j], RLC_FP_DIGS, c3); - dv_swap_cond(t[i][j], v[i][j], RLC_FP_DIGS, c3); - } - } + fp4_copy_sec(t, u, c2); + fp4_copy_sec(x1, y1, c2); + fp4_copy_sec(t, v, c3); + fp4_copy_sec(x1, z1, c3); if (!fp4_srt(t, t)) { RLC_THROW(ERR_NO_VALID); } - - for (int i = 0; i < 2; i++) { - t0z = fp_is_zero(t[i][0]); - fp_prime_back(k, t[i][0]); - t0 = bn_get_bit(k, 0); - fp_prime_back(k, t[i][1]); - t1 = bn_get_bit(k, 0); - /* t[0] == 0 ? sgn0(t[1]) : sgn0(t[0]) */ - s[i] = t0 | (t0z & t1); - } - - t0z = fp2_is_zero(t[0]); - sign ^= (s[0] | (t0z & s[1])); - fp4_neg(u, t); - dv_swap_cond(t[0][0], u[0][0], RLC_FP_DIGS, sign); - dv_swap_cond(t[0][1], u[0][1], RLC_FP_DIGS, sign); - dv_swap_cond(t[1][0], u[1][0], RLC_FP_DIGS, sign); - dv_swap_cond(t[1][1], u[1][1], RLC_FP_DIGS, sign); + fp4_copy_sec(t, u, fp_is_even(t[0][0]) ^ sign); fp4_copy(p->x, x1); fp4_copy(p->y, t); fp4_set_dig(p->z, 1); p->coord = BASIC; } + } else { + if (ep_curve_opt_a() == RLC_ZERO) { + fp4_sqr(x1, u); + fp4_mul(x1, x1, u); + fp4_sqr(y1, t); + fp4_add(x1, x1, ctx->ep4_b); + fp4_sub(x1, x1, y1); + fp4_dbl(y1, y1); + fp4_add(y1, y1, x1); + fp4_copy(z1, u); + fp_mul(z1[0][0], z1[0][0], ctx->ep_map_c[4]); + fp_mul(z1[0][1], z1[0][1], ctx->ep_map_c[4]); + fp_mul(z1[1][0], z1[1][0], ctx->ep_map_c[4]); + fp_mul(z1[1][1], z1[1][1], ctx->ep_map_c[4]); + fp4_mul(x1, x1, z1); + fp4_mul(z1, z1, t); + fp4_dbl(z1, z1); + + fp4_dbl(y, y1); + fp4_sqr(y, y); + fp4_mul(v, y1, u); + fp4_sub(v, x1, v); + fp4_mul(v, v, z1); + fp4_mul(w, y1, z1); + fp4_dbl(w, w); + + if (fp4_is_zero(w)) { + ep4_set_infty(p); + } else { + fp4_inv(w, w); + fp4_mul(x1, v, w); + fp4_add(y1, u, x1); + fp4_neg(y1, y1); + fp4_mul(z1, y, w); + fp4_sqr(z1, z1); + fp4_add(z1, z1, u); + + ep4_rhs(t, x1); + ep4_rhs(u, y1); + ep4_rhs(v, z1); + + dig_t c2 = fp4_is_sqr(u); + dig_t c3 = fp4_is_sqr(v); + + fp4_copy_sec(x1, y1, c2); + fp4_copy_sec(t, u, c2); + fp4_copy_sec(x1, z1, c3); + fp4_copy_sec(t, v, c3); + + if (!fp4_srt(t, t)) { + RLC_THROW(ERR_NO_VALID); + } + + for (int i = 0; i < 2; i++) { + t0z = fp_is_zero(t[i][0]); + fp_prime_back(k, t[i][0]); + t0 = bn_get_bit(k, 0); + fp_prime_back(k, t[i][1]); + t1 = bn_get_bit(k, 0); + /* t[0] == 0 ? sgn0(t[1]) : sgn0(t[0]) */ + s[i] = t0 | (t0z & t1); + } + + t0z = fp2_is_zero(t[0]); + sign ^= (s[0] | (t0z & s[1])); + + fp4_neg(u, t); + fp4_copy_sec(t, u, sign); + + fp4_copy(p->x, x1); + fp4_copy(p->y, t); + fp4_set_dig(p->z, 1); + p->coord = BASIC; + } + } } ep4_mul_cof(p, p); @@ -287,7 +285,9 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len) { RLC_FINALLY { bn_free(k); fp4_free(a); + fp4_free(b); fp4_free(c); + fp4_free(d); fp4_free(t); fp4_free(u); fp4_free(v); @@ -296,6 +296,9 @@ void ep4_map(ep4_t p, const uint8_t *msg, size_t len) { fp4_free(x1); fp4_free(y1); fp4_free(z1); + fp4_free(den[0]); + fp4_free(den[1]); + fp4_free(den[2]); RLC_FREE(h); } } diff --git a/src/epx/relic_ep4_mul.c b/src/epx/relic_ep4_mul.c index 41bf5390b..a6cb8a5ba 100644 --- a/src/epx/relic_ep4_mul.c +++ b/src/epx/relic_ep4_mul.c @@ -24,20 +24,17 @@ /** * @file * - * Implementation of point multiplication on prime elliptic curves over - * quadratic extensions. + * Implementation of point multiplication on prime elliptic curves over a + * quartic extension field. * * @ingroup epx */ - #include "relic_core.h" /*============================================================================*/ /* Private definitions */ /*============================================================================*/ -#if EP_MUL == LWNAF || !defined(STRIP) - #if defined(EP_ENDOM) static void ep4_psi(ep4_t r, const ep4_t p) { @@ -53,6 +50,8 @@ static void ep4_psi(ep4_t r, const ep4_t p) { RLC_TRY { ep4_new(q); + ep4_copy(r, p); + switch (ep_curve_is_pairf()) { case EP_K16: /* u = (2*p^5 - p) mod r */ @@ -81,6 +80,8 @@ static void ep4_psi(ep4_t r, const ep4_t p) { } } +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep4_mul_glv_imp(ep4_t r, const ep4_t p, const bn_t k) { size_t l, _l[8]; bn_t n, _k[8], u; @@ -154,10 +155,133 @@ static void ep4_mul_glv_imp(ep4_t r, const ep4_t p, const bn_t k) { } } +#endif /* EP_MUL == LWNAF */ + +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep4_mul_reg_gls(ep4_t r, const ep4_t p, const bn_t k) { + int8_t reg[8][RLC_FP_BITS + 1], b[8], s[8], c0, n0; + ep4_t q, w, t[8][1 << (RLC_WIDTH - 2)]; + bn_t n, _k[8], u; + size_t l, len, _l[8]; + + bn_null(n); + bn_null(u); + ep4_null(q); + ep4_null(w); + + RLC_TRY { + bn_new(n); + bn_new(u); + ep4_new(q); + ep4_new(w); + for (size_t i = 0; i < 8; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep4_null(t[i][j]); + ep4_new(t[i][j]); + } + } + + ep4_curve_get_ord(n); + fp_prime_get_par(u); + bn_mod(_k[0], k, n); + bn_rec_frb(_k, 8, _k[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + /* Make some extra room for BN curves that grow subscalars by 1. */ + len = bn_bits(u) + (ep_curve_is_pairf() == EP_BN); + ep4_norm(t[0][0], p); + for (size_t i = 0; i < 8; i++) { + s[i] = bn_sign(_k[i]); + bn_abs(_k[i], _k[i]); + b[i] = bn_is_even(_k[i]); + _k[i]->dp[0] |= b[i]; + + _l[i] = RLC_FP_BITS + 1; + bn_rec_reg(reg[i], &_l[i], _k[i], len, RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + ep4_psi(t[i][0], t[i - 1][0]); + } + } + + for (size_t i = 0; i < 8; i++) { + ep4_neg(q, t[i][0]); + fp4_copy_sec(q->y, t[i][0]->y, s[i] == RLC_POS); + ep4_tab(t[i], q, RLC_WIDTH); + } + +#if defined(EP_MIXED) + fp4_set_dig(w->z, 1); + w->coord = BASIC; +#else + w->coord = = EP_ADD; +#endif + + ep4_set_infty(r); + for (int j = l - 1; j >= 0; j--) { + for (size_t i = 0; i < RLC_WIDTH - 1; i++) { + ep4_dbl(r, r); + } + + for (size_t i = 0; i < 8; i++) { + n0 = reg[i][j]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + + for (size_t m = 0; m < (1 << (RLC_WIDTH - 2)); m++) { + fp4_copy_sec(w->x, t[i][m]->x, m == n0); + fp4_copy_sec(w->y, t[i][m]->y, m == n0); + #if !defined(EP_MIXED) + fp4_copy_sec(w->z, t[i][m]->z, m == n0); + #endif + } + + ep4_neg(q, w); + fp4_copy_sec(q->y, w->y, c0 == 0); + ep4_add(r, r, q); + } + } + + for (size_t i = 0; i < 8; i++) { + /* Tables are built with points already negated, so no need here. */ + ep4_sub(q, r, t[i][0]); + fp4_copy_sec(r->x, q->x, b[i]); + fp4_copy_sec(r->y, q->y, b[i]); + fp4_copy_sec(r->z, q->z, b[i]); + } + + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + ep4_free(q); + ep4_free(w); + for (int i = 0; i < 4; i++) { + bn_free(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep4_free(t[i][j]); + } + } + } +} + +#endif /* EP_MUL == LWREG */ #endif /* EP_ENDOM */ #if defined(EP_PLAIN) || defined(EP_SUPER) +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep4_mul_naf_imp(ep4_t r, const ep4_t p, const bn_t k) { int i, n; int8_t naf[RLC_FP_BITS + 1]; @@ -206,9 +330,95 @@ static void ep4_mul_naf_imp(ep4_t r, const ep4_t p, const bn_t k) { } } -#endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_MUL == LWNAF */ +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep4_mul_reg_imp(ep4_t r, const ep4_t p, const bn_t k) { + bn_t _k; + int8_t s, reg[1 + RLC_CEIL(RLC_FP_BITS + 1, RLC_WIDTH - 1)]; + ep4_t t[1 << (RLC_WIDTH - 2)], u, v; + size_t l, n; + + bn_null(_k); + + RLC_TRY { + bn_new(_k); + ep4_new(u); + ep4_new(v); + /* Prepare the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep4_null(t[i]); + ep4_new(t[i]); + } + /* Compute the precomputation table. */ + ep4_tab(t, p, RLC_WIDTH); + + ep4_curve_get_ord(_k); + n = bn_bits(_k); + + /* Make a copy of the scalar for processing. */ + bn_abs(_k, k); + _k->dp[0] |= 1; + + /* Compute the regular w-NAF representation of k. */ + l = RLC_CEIL(n, RLC_WIDTH - 1) + 1; + bn_rec_reg(reg, &l, _k, n, RLC_WIDTH); + +#if defined(EP_MIXED) + fp4_set_dig(u->z, 1); + u->coord = BASIC; +#else + u->coord = EP_ADD; +#endif + ep4_set_infty(r); + for (int i = l - 1; i >= 0; i--) { + for (size_t j = 0; j < RLC_WIDTH - 1; j++) { + ep4_dbl(r, r); + } + + n = reg[i]; + s = (n >> 7); + n = ((n ^ s) - s) >> 1; + + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + fp4_copy_sec(u->x, t[j]->x, j == n); + fp4_copy_sec(u->y, t[j]->y, j == n); +#if !defined(EP_MIXED) + fp_copy_sec(u->z, t[j]->z, j == n); +#endif + } + ep4_neg(v, u); + fp4_copy_sec(u->y, v->y, s != 0); + ep4_add(r, r, u); + } + /* t[0] has an unmodified copy of p. */ + ep4_sub(u, r, t[0]); + fp4_copy_sec(r->x, u->x, bn_is_even(k)); + fp4_copy_sec(r->y, u->y, bn_is_even(k)); + fp4_copy_sec(r->z, u->z, bn_is_even(k)); + /* Convert r to affine coordinates. */ + ep4_norm(r, r); + ep4_neg(u, r); + fp4_copy_sec(r->y, u->y, bn_sign(k) == RLC_NEG); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep4_free(t[i]); + } + bn_free(_k); + ep4_free(u); + ep4_free(v); + } +} + +#endif /* EP_MUL == LWREG */ +#endif /* EP_PLAIN || EP_SUPER */ + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -371,7 +581,7 @@ void ep4_mul_monty(ep4_t r, const ep4_t p, const bn_t k) { bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); - dv_swap_cond(l->dp, n->dp, RLC_MAX(l->used, n->used), + dv_swap_sec(l->dp, n->dp, RLC_MAX(l->used, n->used), bn_get_bit(l, bits) == 0); l->used = RLC_SEL(l->used, n->used, bn_get_bit(l, bits) == 0); @@ -384,32 +594,32 @@ void ep4_mul_monty(ep4_t r, const ep4_t p, const bn_t k) { for (int i = bits - 1; i >= 0; i--) { int j = bn_get_bit(l, i); - dv_swap_cond(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); ep4_add(t[0], t[0], t[1]); ep4_dbl(t[1], t[1]); - dv_swap_cond(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0][0], t[1]->x[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[0][1], t[1]->x[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1][0], t[1]->x[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[1][1], t[1]->x[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0][0], t[1]->y[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[0][1], t[1]->y[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1][0], t[1]->y[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[1][1], t[1]->y[1][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0][0], t[1]->z[0][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[0][1], t[1]->z[0][1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1][0], t[1]->z[1][0], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[1][1], t[1]->z[1][1], RLC_FP_DIGS, j ^ 1); } ep4_norm(r, t[0]); @@ -449,6 +659,28 @@ void ep4_mul_lwnaf(ep4_t r, const ep4_t p, const bn_t k) { #endif +#if EP_MUL == LWREG || !defined(STRIP) + +void ep4_mul_lwreg(ep4_t r, const ep4_t p, const bn_t k) { + if (bn_is_zero(k) || ep4_is_infty(p)) { + ep4_set_infty(r); + return; + } + +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + ep4_mul_reg_gls(r, p, k); + return; + } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + ep4_mul_reg_imp(r, p, k); +#endif +} + +#endif + void ep4_mul_gen(ep4_t r, const bn_t k) { if (bn_is_zero(k)) { ep4_set_infty(r); diff --git a/src/epx/relic_ep4_mul_cof.c b/src/epx/relic_ep4_mul_cof.c index 65d4f7f64..459a64f87 100644 --- a/src/epx/relic_ep4_mul_cof.c +++ b/src/epx/relic_ep4_mul_cof.c @@ -25,14 +25,13 @@ * @file * * Implementation of point multiplication of a prime elliptic curve over a - * quartic extension by the curve cofactor. + * quartic extension field by the curve cofactor. * * @ingroup epx */ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Public definitions */ @@ -370,7 +369,7 @@ void ep4_mul_cof(ep4_t r, const ep4_t p) { default: /* Now, multiply by cofactor to get the correct group. */ ep4_curve_get_cof(k); - ep4_mul_basic(r, p, k); + ep4_mul_big(r, p, k); break; } } RLC_CATCH_ANY { diff --git a/src/epx/relic_ep4_mul_fix.c b/src/epx/relic_ep4_mul_fix.c index 33b8dac4c..9aa789bbb 100644 --- a/src/epx/relic_ep4_mul_fix.c +++ b/src/epx/relic_ep4_mul_fix.c @@ -25,7 +25,7 @@ * @file * * Implementation of fixed point multiplication on a prime elliptic curve over - * a quartic extension. + * a quartic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep4_mul_sim.c b/src/epx/relic_ep4_mul_sim.c index 719332f38..ff4c62c3b 100644 --- a/src/epx/relic_ep4_mul_sim.c +++ b/src/epx/relic_ep4_mul_sim.c @@ -25,7 +25,7 @@ * @file * * Implementation of simultaneous point multiplication on a prime elliptic - * curve over a quartic extension. + * curve over a quartic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep4_neg.c b/src/epx/relic_ep4_neg.c index 604fc116e..f2cf6b952 100644 --- a/src/epx/relic_ep4_neg.c +++ b/src/epx/relic_ep4_neg.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point negation on elliptic prime curves over quartic - * extensions. + * Implementation of point negation on elliptic prime curves over a quartic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep4_norm.c b/src/epx/relic_ep4_norm.c index ca2646dd5..6576d3ace 100644 --- a/src/epx/relic_ep4_norm.c +++ b/src/epx/relic_ep4_norm.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point normalization on prime elliptic curves over quartic - * extensions. + * Implementation of point normalization on prime elliptic curves over a quartic + * extension field. * * @ingroup epx */ @@ -43,36 +43,45 @@ * * @param r - the result. * @param p - the point to normalize. + * @param inv - the flag to indicate if z is already inverted. */ -static void ep4_norm_imp(ep4_t r, const ep4_t p, int inverted) { +static void ep4_norm_imp(ep4_t r, const ep4_t p, int inv) { if (p->coord != BASIC) { - fp4_t t0, t1; + fp4_t t; - fp4_null(t0); - fp4_null(t1); + fp4_null(t); RLC_TRY { + fp4_new(t); - fp4_new(t0); - fp4_new(t1); - - if (inverted) { - fp4_copy(t1, p->z); + if (inv) { + fp4_copy(r->z, p->z); } else { - fp4_inv(t1, p->z); + fp4_inv(r->z, p->z); + } + + switch (p->coord) { + case PROJC: + fp4_mul(r->x, p->x, r->z); + fp4_mul(r->y, p->y, r->z); + break; + case JACOB: + fp4_sqr(t, r->z); + fp4_mul(r->x, p->x, t); + fp4_mul(t, t, r->z); + fp4_mul(r->y, p->y, t); + break; + default: + ep4_copy(r, p); + break; } - fp4_sqr(t0, t1); - fp4_mul(r->x, p->x, t0); - fp4_mul(t0, t0, t1); - fp4_mul(r->y, p->y, t0); fp4_set_dig(r->z, 1); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { - fp4_free(t0); - fp4_free(t1); + fp4_free(t); } } @@ -92,17 +101,18 @@ void ep4_norm(ep4_t r, const ep4_t p) { } if (p->coord == BASIC) { - /* If the point is represented in affine coordinates, we just copy it. */ + /* If the point is represented in affine coordinates, just copy it. */ ep4_copy(r, p); + return; } #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) ep4_norm_imp(r, p, 0); -#endif +#endif /* EP_ADD == PROJC */ } void ep4_norm_sim(ep4_t *r, const ep4_t *t, int n) { int i; - fp4_t *a = RLC_ALLOCA(fp4_t, n); + fp4_t* a = RLC_ALLOCA(fp4_t, n); RLC_TRY { if (a == NULL) { @@ -114,18 +124,20 @@ void ep4_norm_sim(ep4_t *r, const ep4_t *t, int n) { fp4_copy(a[i], t[i]->z); } - fp4_inv_sim(a, a, n); + fp4_inv_sim(a, (const fp4_t *)a, n); for (i = 0; i < n; i++) { fp4_copy(r[i]->x, t[i]->x); fp4_copy(r[i]->y, t[i]->y); - fp4_copy(r[i]->z, a[i]); + if (!ep4_is_infty(t[i])) { + fp4_copy(r[i]->z, a[i]); + } } #if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) for (i = 0; i < n; i++) { ep4_norm_imp(r[i], r[i], 1); } -#endif +#endif /* EP_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/epx/relic_ep4_util.c b/src/epx/relic_ep4_util.c index c41642956..8564d9cca 100644 --- a/src/epx/relic_ep4_util.c +++ b/src/epx/relic_ep4_util.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of comparison for points on prime elliptic curves over - * quartic extensions. + * Implementation of comparison for points on prime elliptic curves over a + * quartic extension field. * * @ingroup epx */ @@ -89,13 +89,18 @@ void ep4_blind(ep4_t r, const ep4_t p) { #if EP_ADD == BASIC (void)rand; ep4_copy(r, p); -#else +#elif EP_ADD == PROJC + fp4_mul(r->x, p->x, rand); + fp4_mul(r->y, p->y, rand); + fp4_mul(r->z, p->z, rand); + r->coord = PROJC; +#elif EP_ADD == JACOB fp4_mul(r->z, p->z, rand); fp4_mul(r->y, p->y, rand); fp4_sqr(rand, rand); fp4_mul(r->x, r->x, rand); fp4_mul(r->y, r->y, rand); - r->coord = EP_ADD; + r->coord = JACOB; #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -104,17 +109,15 @@ void ep4_blind(ep4_t r, const ep4_t p) { } } -void ep4_rhs(fp4_t rhs, const ep4_t p) { - fp4_t t0, t1; +void ep4_rhs(fp4_t rhs, const fp4_t x) { + fp4_t t0; fp4_null(t0); - fp4_null(t1); RLC_TRY { fp4_new(t0); - fp4_new(t1); - fp4_sqr(t0, p->x); /* x1^2 */ + fp4_sqr(t0, x); switch (ep4_curve_opt_a()) { case RLC_ZERO: @@ -130,17 +133,15 @@ void ep4_rhs(fp4_t rhs, const ep4_t p) { fp_add_dig(t0[0][0], t0[0][0], 2); break; case RLC_TINY: - ep4_curve_get_a(t1); - fp4_mul_dig(t0, t0, t1[0][0][0]); + fp4_mul_dig(t0, t0, ep4_curve_get_a()[0][0][0]); break; #endif default: - ep4_curve_get_a(t1); - fp4_add(t0, t0, t1); + fp4_add(t0, t0, ep4_curve_get_a()); break; } - fp4_mul(t0, t0, p->x); /* x1^3 + a * x */ + fp4_mul(t0, t0, x); switch (ep4_curve_opt_b()) { case RLC_ZERO: @@ -156,13 +157,11 @@ void ep4_rhs(fp4_t rhs, const ep4_t p) { fp_add_dig(t0[0][0], t0[0][0], 2); break; case RLC_TINY: - ep4_curve_get_b(t1); - fp4_mul_dig(t0, t0, t1[0][0][0]); + fp4_mul_dig(t0, t0, ep4_curve_get_b()[0][0][0]); break; #endif default: - ep4_curve_get_b(t1); - fp4_add(t0, t0, t1); + fp4_add(t0, t0, ep4_curve_get_b()); break; } @@ -171,11 +170,9 @@ void ep4_rhs(fp4_t rhs, const ep4_t p) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { fp4_free(t0); - fp4_free(t1); } } - int ep4_on_curve(const ep4_t p) { ep4_t t; int r = 0; @@ -187,7 +184,7 @@ int ep4_on_curve(const ep4_t p) { ep4_norm(t, p); - ep4_rhs(t->x, t); + ep4_rhs(t->x, t->x); fp4_sqr(t->y, t->y); r = (fp4_cmp(t->x, t->y) == RLC_EQ) || ep4_is_infty(p); diff --git a/src/epx/relic_ep8_add.c b/src/epx/relic_ep8_add.c index 15dde9000..687998124 100644 --- a/src/epx/relic_ep8_add.c +++ b/src/epx/relic_ep8_add.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of addition on prime elliptic curves over quartic - * extensions. + * Implementation of addition on prime elliptic curves over an octic extension + * field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_add_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -42,312 +43,62 @@ * 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 */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) -#if defined(EP_MIXED) || !defined(STRIP) +/** + * Adds a point represented in homogeneous coordinates to a point represented in + * 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. + */ +TMPL_ADD_PROJC_MIX(ep8, fp8); /** - * Adds a point represented in affine coordinates to a point represented in - * projective coordinates. + * Adds two points represented in homogeneous coordinates on an ordinary prime + * elliptic curve. * - * @param r - the result. - * @param s - the slope. - * @param p - the affine point. - * @param q - the projective point. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep8_add_projc_mix(ep8_t r, const ep8_t p, const ep8_t q) { - fp8_t t0, t1, t2, t3, t4, t5, t6; +TMPL_ADD_PROJC_IMP(ep8, fp8); - fp8_null(t0); - fp8_null(t1); - fp8_null(t2); - fp8_null(t3); - fp8_null(t4); - fp8_null(t5); - fp8_null(t6); +#endif /* EP_ADD == PROJC */ - RLC_TRY { - fp8_new(t0); - fp8_new(t1); - fp8_new(t2); - fp8_new(t3); - fp8_new(t4); - fp8_new(t5); - fp8_new(t6); - - if (p->coord != BASIC) { - /* t0 = z1^2. */ - fp8_sqr(t0, p->z); - - /* t3 = U2 = x2 * z1^2. */ - fp8_mul(t3, q->x, t0); - - /* t1 = S2 = y2 * z1^3. */ - fp8_mul(t1, t0, p->z); - fp8_mul(t1, t1, q->y); - - /* t3 = H = U2 - x1. */ - fp8_sub(t3, t3, p->x); - - /* t1 = R = 2 * (S2 - y1). */ - fp8_sub(t1, t1, p->y); - } else { - /* H = x2 - x1. */ - fp8_sub(t3, q->x, p->x); - - /* t1 = R = 2 * (y2 - y1). */ - fp8_sub(t1, q->y, p->y); - } - - /* t2 = HH = H^2. */ - fp8_sqr(t2, t3); - - /* If E is zero. */ - if (fp8_is_zero(t3)) { - if (fp8_is_zero(t1)) { - /* If I is zero, p = q, should have doubled. */ - ep8_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep8_set_infty(r); - } - } else { - /* t5 = J = H * HH. */ - fp8_mul(t5, t3, t2); - - /* t4 = V = x1 * HH. */ - fp8_mul(t4, p->x, t2); - - /* x3 = R^2 - J - 2 * V. */ - fp8_sqr(r->x, t1); - fp8_sub(r->x, r->x, t5); - fp8_dbl(t6, t4); - fp8_sub(r->x, r->x, t6); - - /* y3 = R * (V - x3) - Y1 * J. */ - fp8_sub(t4, t4, r->x); - fp8_mul(t4, t4, t1); - fp8_mul(t1, p->y, t5); - fp8_sub(r->y, t4, t1); - - if (p->coord != BASIC) { - /* z3 = z1 * H. */ - fp8_mul(r->z, p->z, t3); - } else { - /* z3 = H. */ - fp8_copy(r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); - fp8_free(t2); - fp8_free(t3); - fp8_free(t4); - fp8_free(t5); - fp8_free(t6); - } -} +#if EP_ADD == JACOB || !defined(STRIP) -#endif +/** + * Adds a point represented in Jacobian coordinates to a point represented in + * 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. + */ +TMPL_ADD_JACOB_MIX(ep8, fp8); /** - * Adds two points represented in projective coordinates on an ordinary prime + * Adds two points represented in Jacobian coordinates on an ordinary prime * elliptic curve. * - * @param r - the result. - * @param p - the first point to add. - * @param q - the second point to add. + * @param[out] r - the result. + * @param[in] p - the first point to add. + * @param[in] q - the second point to add. */ -static void ep8_add_projc_imp(ep8_t r, const ep8_t p, const ep8_t q) { -#if defined(EP_MIXED) && defined(STRIP) - ep8_add_projc_mix(r, p, q); -#else /* General addition. */ - fp8_t t0, t1, t2, t3, t4, t5, t6; - - fp8_null(t0); - fp8_null(t1); - fp8_null(t2); - fp8_null(t3); - fp8_null(t4); - fp8_null(t5); - fp8_null(t6); +TMPL_ADD_JACOB_IMP(ep8, fp8); - RLC_TRY { - fp8_new(t0); - fp8_new(t1); - fp8_new(t2); - fp8_new(t3); - fp8_new(t4); - fp8_new(t5); - fp8_new(t6); - - if (q->coord == BASIC) { - ep8_add_projc_mix(r, p, q); - } else { - /* t0 = z1^2. */ - fp8_sqr(t0, p->z); - - /* t1 = z2^2. */ - fp8_sqr(t1, q->z); - - /* t2 = U1 = x1 * z2^2. */ - fp8_mul(t2, p->x, t1); - - /* t3 = U2 = x2 * z1^2. */ - fp8_mul(t3, q->x, t0); - - /* t6 = z1^2 + z2^2. */ - fp8_add(t6, t0, t1); - - /* t0 = S2 = y2 * z1^3. */ - fp8_mul(t0, t0, p->z); - fp8_mul(t0, t0, q->y); - - /* t1 = S1 = y1 * z2^3. */ - fp8_mul(t1, t1, q->z); - fp8_mul(t1, t1, p->y); - - /* t3 = H = U2 - U1. */ - fp8_sub(t3, t3, t2); - - /* t0 = R = 2 * (S2 - S1). */ - fp8_sub(t0, t0, t1); - - fp8_dbl(t0, t0); - - /* If E is zero. */ - if (fp8_is_zero(t3)) { - if (fp8_is_zero(t0)) { - /* If I is zero, p = q, should have doubled. */ - ep8_dbl_projc(r, p); - } else { - /* If I is not zero, q = -p, r = infinity. */ - ep8_set_infty(r); - } - } else { - /* t4 = I = (2*H)^2. */ - fp8_dbl(t4, t3); - fp8_sqr(t4, t4); - - /* t5 = J = H * I. */ - fp8_mul(t5, t3, t4); - - /* t4 = V = U1 * I. */ - fp8_mul(t4, t2, t4); - - /* x3 = R^2 - J - 2 * V. */ - fp8_sqr(r->x, t0); - fp8_sub(r->x, r->x, t5); - fp8_dbl(t2, t4); - fp8_sub(r->x, r->x, t2); - - /* y3 = R * (V - x3) - 2 * S1 * J. */ - fp8_sub(t4, t4, r->x); - fp8_mul(t4, t4, t0); - fp8_mul(t1, t1, t5); - fp8_dbl(t1, t1); - fp8_sub(r->y, t4, t1); - - /* z3 = ((z1 + z2)^2 - z1^2 - z2^2) * H. */ - fp8_add(r->z, p->z, q->z); - fp8_sqr(r->z, r->z); - fp8_sub(r->z, r->z, t6); - fp8_mul(r->z, r->z, t3); - } - } - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); - fp8_free(t2); - fp8_free(t3); - fp8_free(t4); - fp8_free(t5); - fp8_free(t6); - } -#endif -} - -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ /* Public definitions */ @@ -385,7 +136,7 @@ void ep8_add_slp_basic(ep8_t r, fp8_t s, const ep8_t p, const ep8_t q) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep8_add_projc(ep8_t r, const ep8_t p, const ep8_t q) { if (ep8_is_infty(p)) { @@ -398,13 +149,25 @@ void ep8_add_projc(ep8_t r, const ep8_t p, const ep8_t q) { return; } - if (p == q) { - /* TODO: This is a quick hack. Should we fix this? */ - ep8_dbl(r, p); + ep8_add_projc_imp(r, p, q); +} + +#endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep8_add_jacob(ep8_t r, const ep8_t p, const ep8_t q) { + if (ep8_is_infty(p)) { + ep8_copy(r, q); return; } - ep8_add_projc_imp(r, p, q); + if (ep8_is_infty(q)) { + ep8_copy(r, p); + return; + } + + ep8_add_jacob_imp(r, p, q); } #endif @@ -421,7 +184,6 @@ void ep8_sub(ep8_t r, const ep8_t p, const ep8_t q) { RLC_TRY { ep8_new(t); - ep8_neg(t, q); ep8_add(r, p, t); } diff --git a/src/epx/relic_ep8_cmp.c b/src/epx/relic_ep8_cmp.c index cf00e38a6..4e57b8a80 100644 --- a/src/epx/relic_ep8_cmp.c +++ b/src/epx/relic_ep8_cmp.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of utilities for prime elliptic curves over quadratic - * extensions. + * Implementation of utilities for prime elliptic curves over an octic + * extension field. * * @ingroup epx */ @@ -37,46 +37,68 @@ /*============================================================================*/ int ep8_cmp(const ep8_t p, const ep8_t q) { - ep8_t r, s; - int result = RLC_NE; + ep8_t r, s; + int result = RLC_NE; if (ep8_is_infty(p) && ep8_is_infty(q)) { return RLC_EQ; } - ep8_null(r); - ep8_null(s); + ep8_null(r); + ep8_null(s); - RLC_TRY { - ep8_new(r); - ep8_new(s); + RLC_TRY { + ep8_new(r); + ep8_new(s); - if ((p->coord != BASIC) && (q->coord != BASIC)) { - /* If the two points are not normalized, it is faster to compare - * x1 * z2^2 == x2 * z1^2 and y1 * z2^3 == y2 * z1^3. */ - fp8_sqr(r->z, p->z); - fp8_sqr(s->z, q->z); - fp8_mul(r->x, p->x, s->z); - fp8_mul(s->x, q->x, r->z); - fp8_mul(r->z, r->z, p->z); - fp8_mul(s->z, s->z, q->z); - fp8_mul(r->y, p->y, s->z); - fp8_mul(s->y, q->y, r->z); - } else { - ep8_norm(r, p); - ep8_norm(s, q); - } + switch (q->coord) { + case PROJC: + /* If q is in homogeneous projective coordinates, compute + * x1 * z2 and y1 * z2. */ + fp8_mul(r->x, p->x, q->z); + fp8_mul(r->y, p->y, q->z); + break; + case JACOB: + /* If q is in Jacobian projective coordinates, compute + * x2 * z1^2 and y2 * z1^3. */ + fp8_sqr(r->z, q->z); + fp8_mul(r->x, p->x, r->z); + fp8_mul(r->z, r->z, q->z); + fp8_mul(r->y, p->y, r->z); + break; + default: + ep8_copy(r, p); + break; + } - if ((fp8_cmp(r->x, s->x) == RLC_EQ) && - (fp8_cmp(r->y, s->y) == RLC_EQ)) { - result = RLC_EQ; - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } RLC_FINALLY { - ep8_free(r); - ep8_free(s); - } + switch (p->coord) { + /* Now do the same for the other point. */ + case PROJC: + fp8_mul(s->x, q->x, p->z); + fp8_mul(s->y, q->y, p->z); + break; + case JACOB: + fp8_sqr(s->z, p->z); + fp8_mul(s->x, q->x, s->z); + fp8_mul(s->z, s->z, p->z); + fp8_mul(s->y, q->y, s->z); + break; + default: + ep8_copy(s, q); + break; + } - return result; + if ((fp8_cmp(r->x, s->x) == RLC_EQ) && (fp8_cmp(r->y, s->y) == RLC_EQ)) { + result = RLC_EQ; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + ep8_free(r); + ep8_free(s); + } + + return result; } diff --git a/src/epx/relic_ep8_curve.c b/src/epx/relic_ep8_curve.c index 90d130d07..02dae23b6 100644 --- a/src/epx/relic_ep8_curve.c +++ b/src/epx/relic_ep8_curve.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of configuration of prime elliptic curves over octic - * extensions. + * Implementation of configuration of prime elliptic curves over an octic + * extension field. * * @ingroup epx */ @@ -221,6 +221,49 @@ int ep8_curve_opt_b(void) { return core_get()->ep8_opt_b; } +void ep8_curve_mul_a(fp8_t c, const fp8_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep8_opt_a) { + case RLC_ZERO: + fp8_zero(c); + break; + case RLC_ONE: + fp8_copy(c, a); + break; + case RLC_TWO: + fp8_dbl(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp8_mul_dig(c, a, ctx->ep8_a[0]); + break; +#endif + default: + fp8_mul(c, a, ctx->ep8_a); + break; + } +} + +void ep8_curve_mul_b(fp8_t c, const fp8_t a) { + ctx_t *ctx = core_get(); + switch (ctx->ep8_opt_b) { + case RLC_ZERO: + fp8_zero(c); + break; + case RLC_ONE: + fp8_copy(c, a); + break; +#if FP_RDC != MONTY + case RLC_TINY: + fp8_mul_dig(c, a, ctx->ep8_b[0]); + break; +#endif + default: + fp8_mul(c, a, ctx->ep8_b); + break; + } +} + int ep8_curve_is_twist(void) { return core_get()->ep8_is_twist; } @@ -229,12 +272,12 @@ void ep8_curve_get_gen(ep8_t g) { ep8_copy(g, core_get()->ep8_g); } -void ep8_curve_get_a(fp8_t a) { - fp8_copy(a, core_get()->ep8_a); +fp4_t *ep8_curve_get_a(void) { + return core_get()->ep8_a; } -void ep8_curve_get_b(fp8_t b) { - fp8_copy(b, core_get()->ep8_b); +fp4_t *ep8_curve_get_b(void) { + return core_get()->ep8_b; } void ep8_curve_get_ord(bn_t n) { diff --git a/src/epx/relic_ep8_dbl.c b/src/epx/relic_ep8_dbl.c index 0139e9f8d..76e62b41d 100644 --- a/src/epx/relic_ep8_dbl.c +++ b/src/epx/relic_ep8_dbl.c @@ -24,13 +24,14 @@ /** * @file * - * Implementation of doubling on elliptic prime curves over quartic - * extensions. + * Implementation of doubling on elliptic prime curves over an octic extension + * field. * * @ingroup epx */ #include "relic_core.h" +#include "relic_ep_dbl_tmpl.h" /*============================================================================*/ /* Private definitions */ @@ -43,201 +44,41 @@ * elliptic curve. * * @param[out] r - the result. - * @param[out] s - the resulting slope. + * @param[out] s - the slope. * @param[in] p - the point to double. */ -static void ep8_dbl_basic_imp(ep8_t r, fp8_t s, const ep8_t p) { - 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 = 1/(2 * y1). */ - fp8_dbl(t0, p->y); - fp8_inv(t0, t0); - - /* t1 = 3 * x1^2 + a. */ - fp8_sqr(t1, p->x); - fp8_copy(t2, t1); - fp8_dbl(t1, t1); - fp8_add(t1, t1, t2); - - ep8_curve_get_a(t2); - fp8_add(t1, t1, t2); - - /* t1 = (3 * x1^2 + a)/(2 * y1). */ - fp8_mul(t1, t1, t0); - - if (s != NULL) { - fp8_copy(s, t1); - } - - /* t2 = t1^2. */ - fp8_sqr(t2, t1); - - /* x3 = t1^2 - 2 * x1. */ - fp8_dbl(t0, p->x); - fp8_sub(t0, t2, t0); - - /* y3 = t1 * (x1 - x3) - y1. */ - fp8_sub(t2, p->x, t0); - fp8_mul(t1, t1, t2); - - fp8_sub(r->y, t1, p->y); - - fp8_copy(r->x, t0); - fp8_copy(r->z, p->z); - - r->coord = BASIC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); - fp8_free(t2); - } -} +TMPL_DBL_BASIC_IMP(ep8, fp8); #endif /* EP_ADD == BASIC */ -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) /** - * Doubles a point represented in affine coordinates on an ordinary prime + * Doubles a point represented in projective coordinates on an ordinary prime * elliptic curve. * - * @param[out] r - the result. - * @param[in] p - the point to double. + * @param r - the result. + * @param p - the point to double. */ -static void ep8_dbl_projc_imp(ep8_t r, const ep8_t p) { - fp8_t t0, t1, t2, t3, t4, t5; - - fp8_null(t0); - fp8_null(t1); - fp8_null(t2); - fp8_null(t3); - fp8_null(t4); - fp8_null(t5); - - RLC_TRY { - fp8_new(t0); - fp8_new(t1); - fp8_new(t2); - fp8_new(t3); - fp8_new(t4); - fp8_new(t5); - - if (ep_curve_opt_a() == RLC_ZERO) { - fp8_sqr(t0, p->x); - fp8_add(t2, t0, t0); - fp8_add(t0, t2, t0); - - fp8_sqr(t3, p->y); - fp8_mul(t1, t3, p->x); - fp8_add(t1, t1, t1); - fp8_add(t1, t1, t1); - fp8_sqr(r->x, t0); - fp8_add(t2, t1, t1); - fp8_sub(r->x, r->x, t2); - fp8_mul(r->z, p->z, p->y); - fp8_add(r->z, r->z, r->z); - fp8_add(t3, t3, t3); - - fp8_sqr(t3, t3); - fp8_add(t3, t3, t3); - fp8_sub(t1, t1, r->x); - fp8_mul(r->y, t0, t1); - fp8_sub(r->y, r->y, t3); - } else { - /* dbl-2007-bl formulas: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ - /* http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl */ - - /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ - fp8_sqr(t0, p->x); - fp8_sqr(t1, p->y); - fp8_sqr(t2, t1); - - if (p->coord != BASIC) { - /* t3 = z1^2. */ - fp8_sqr(t3, p->z); +TMPL_DBL_PROJC_IMP(ep8, fp8); - if (ep_curve_get_a() == RLC_ZERO) { - /* z3 = 2 * y1 * z1. */ - fp8_mul(r->z, p->y, p->z); - fp8_dbl(r->z, r->z); - } else { - /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ - fp8_add(r->z, p->y, p->z); - fp8_sqr(r->z, r->z); - fp8_sub(r->z, r->z, t1); - fp8_sub(r->z, r->z, t3); - } - } else { - /* z3 = 2 * y1. */ - fp8_dbl(r->z, p->y); - } - - /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ - fp8_add(t4, p->x, t1); - fp8_sqr(t4, t4); - fp8_sub(t4, t4, t0); - fp8_sub(t4, t4, t2); - fp8_dbl(t4, t4); - - /* t5 = M = 3 * x1^2 + a * z1^4. */ - fp8_dbl(t5, t0); - fp8_add(t5, t5, t0); - if (p->coord != BASIC) { - fp8_sqr(t3, t3); - ep8_curve_get_a(t1); - fp8_mul(t1, t3, t1); - fp8_add(t5, t5, t1); - } else { - ep8_curve_get_a(t1); - fp8_add(t5, t5, t1); - } - - /* x3 = T = M^2 - 2 * S. */ - fp8_sqr(r->x, t5); - fp8_dbl(t1, t4); - fp8_sub(r->x, r->x, t1); +#endif /* EP_ADD == PROJC */ - /* y3 = M * (S - T) - 8 * y1^4. */ - fp8_dbl(t2, t2); - fp8_dbl(t2, t2); - fp8_dbl(t2, t2); - fp8_sub(t4, t4, r->x); - fp8_mul(t5, t5, t4); - fp8_sub(r->y, t5, t2); - } +#if EP_ADD == JACOB || !defined(STRIP) - r->coord = PROJC; - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); - fp8_free(t2); - fp8_free(t3); - fp8_free(t4); - fp8_free(t5); - } -} +/** + * Doubles a point represented in Jacobian coordinates on an ordinary prime + * elliptic curve. + * + * @param r - the result. + * @param p - the point to double. + */ +TMPL_DBL_JACOB_IMP(ep8, fp8); -#endif /* EP_ADD == PROJC */ +#endif /* EP_ADD == JACOB */ /*============================================================================*/ - /* Public definitions */ +/* Public definitions */ /*============================================================================*/ #if EP_ADD == BASIC || !defined(STRIP) @@ -247,7 +88,6 @@ void ep8_dbl_basic(ep8_t r, const ep8_t p) { ep8_set_infty(r); return; } - ep8_dbl_basic_imp(r, NULL, p); } @@ -262,7 +102,7 @@ void ep8_dbl_slp_basic(ep8_t r, fp8_t s, const ep8_t p) { #endif -#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) +#if EP_ADD == PROJC || !defined(STRIP) void ep8_dbl_projc(ep8_t r, const ep8_t p) { if (ep8_is_infty(p)) { @@ -274,3 +114,16 @@ void ep8_dbl_projc(ep8_t r, const ep8_t p) { } #endif + +#if EP_ADD == JACOB || !defined(STRIP) + +void ep8_dbl_jacob(ep8_t r, const ep8_t p) { + if (ep8_is_infty(p)) { + ep8_set_infty(r); + return; + } + + ep8_dbl_jacob_imp(r, p); +} + +#endif diff --git a/src/epx/relic_ep8_frb.c b/src/epx/relic_ep8_frb.c index 1cd8c4f72..4d3e4ed43 100644 --- a/src/epx/relic_ep8_frb.c +++ b/src/epx/relic_ep8_frb.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of frobenius action on prime elliptic curves over - * quartic extensions. + * Implementation of frobenius action on prime elliptic curves over an octic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep8_map.c b/src/epx/relic_ep8_map.c index ce8420a74..05f11180d 100644 --- a/src/epx/relic_ep8_map.c +++ b/src/epx/relic_ep8_map.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of hashing to a prime elliptic curve over a quadratic - * extension. + * Implementation of hashing to a prime elliptic curve over an octic extension + * field. * * @ingroup epx */ @@ -124,33 +124,17 @@ void ep8_map(ep8_t p, const uint8_t *msg, size_t len) { fp8_sqr(z1, z1); fp8_add(z1, z1, u); - ep8_curve_get_b(w); - - fp8_sqr(t, x1); - fp8_mul(t, t, x1); - fp8_add(t, t, w); - - fp8_sqr(u, y1); - fp8_mul(u, u, y1); - fp8_add(u, u, w); - - fp8_sqr(v, z1); - fp8_mul(v, v, z1); - fp8_add(v, v, w); + ep8_rhs(t, x1); + ep8_rhs(u, y1); + ep8_rhs(v, z1); c2 = fp8_is_sqr(u); c3 = fp8_is_sqr(v); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - for (int l = 0; l < 2; l++) { - dv_swap_cond(x1[i][j][l], y1[i][j][l], RLC_FP_DIGS, c2); - dv_swap_cond(t[i][j][l], u[i][j][l], RLC_FP_DIGS, c2); - dv_swap_cond(x1[i][j][l], z1[i][j][l], RLC_FP_DIGS, c3); - dv_swap_cond(t[i][j][l], v[i][j][l], RLC_FP_DIGS, c3); - } - } - } + fp8_copy_sec(t, u, c2); + fp8_copy_sec(x1, y1, c2); + fp8_copy_sec(t, v, c3); + fp8_copy_sec(x1, z1, c3); if (!fp8_srt(t, t)) { RLC_THROW(ERR_NO_VALID); @@ -172,13 +156,7 @@ void ep8_map(ep8_t p, const uint8_t *msg, size_t len) { } fp8_neg(u, t); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - for (int l = 0; l < 2; l++) { - dv_swap_cond(t[i][j][l], u[i][j][l], RLC_FP_DIGS, sign); - } - } - } + fp8_copy_sec(t, u, sign); fp8_copy(p->x, x1); fp8_copy(p->y, t); diff --git a/src/epx/relic_ep8_mul.c b/src/epx/relic_ep8_mul.c index 8e0b0f60a..5300e8933 100644 --- a/src/epx/relic_ep8_mul.c +++ b/src/epx/relic_ep8_mul.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point multiplication on prime elliptic curves over - * quadratic extensions. + * Implementation of point multiplication on prime elliptic curves over an + * octic extension field. * * @ingroup epx */ @@ -36,10 +36,10 @@ /* Private definitions */ /*============================================================================*/ -#if EP_MUL == LWNAF || !defined(STRIP) - #if defined(EP_ENDOM) +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep8_mul_glv_imp(ep8_t r, const ep8_t p, const bn_t k) { size_t l, _l[16]; bn_t n, _k[16], u; @@ -106,14 +106,136 @@ static void ep8_mul_glv_imp(ep8_t r, const ep8_t p, const bn_t k) { bn_free(_k[i]); ep8_free(q[i]); } + } +} + +#endif /* EP_MUL == LWNAF */ + +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep8_mul_reg_gls(ep8_t r, const ep8_t p, const bn_t k) { + int8_t reg[16][RLC_FP_BITS + 1], b[16], s[16], c0, n0; + ep8_t q, w, t[16][1 << (RLC_WIDTH - 2)]; + bn_t n, _k[16], u; + size_t l, len, _l[16]; + + bn_null(n); + bn_null(u); + ep8_null(q); + ep8_null(w); + + RLC_TRY { + bn_new(n); + bn_new(u); + ep8_new(q); + ep8_new(w); + for (size_t i = 0; i < 16; i++) { + bn_null(_k[i]); + bn_new(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep8_null(t[i][j]); + ep8_new(t[i][j]); + } + } + + ep8_curve_get_ord(n); + fp_prime_get_par(u); + bn_mod(_k[0], k, n); + bn_rec_frb(_k, 16, _k[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + /* Make some extra room for BN curves that grow subscalars by 1. */ + len = bn_bits(u) + (ep_curve_is_pairf() == EP_BN); + ep8_norm(t[0][0], p); + for (size_t i = 0; i < 16; i++) { + s[i] = bn_sign(_k[i]); + bn_abs(_k[i], _k[i]); + b[i] = bn_is_even(_k[i]); + _k[i]->dp[0] |= b[i]; + + _l[i] = RLC_FP_BITS + 1; + bn_rec_reg(reg[i], &_l[i], _k[i], len, RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + ep8_frb(t[i][0], t[i - 1][0], 1); + } + } + + for (size_t i = 0; i < 16; i++) { + ep8_neg(q, t[i][0]); + fp8_copy_sec(q->y, t[i][0]->y, s[i] == RLC_POS); + ep8_tab(t[i], q, RLC_WIDTH); + } + +#if defined(EP_MIXED) + fp8_set_dig(w->z, 1); + w->coord = BASIC; +#else + w->coord = = EP_ADD; +#endif + + ep8_set_infty(r); + for (int j = l - 1; j >= 0; j--) { + for (size_t i = 0; i < RLC_WIDTH - 1; i++) { + ep8_dbl(r, r); + } + + for (size_t i = 0; i < 16; i++) { + n0 = reg[i][j]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + + for (size_t m = 0; m < (1 << (RLC_WIDTH - 2)); m++) { + fp8_copy_sec(w->x, t[i][m]->x, m == n0); + fp8_copy_sec(w->y, t[i][m]->y, m == n0); + #if !defined(EP_MIXED) + fp8_copy_sec(w->z, t[i][m]->z, m == n0); + #endif + } + + ep8_neg(q, w); + fp8_copy_sec(q->y, w->y, c0 == 0); + ep8_add(r, r, q); + } + } + for (size_t i = 0; i < 16; i++) { + /* Tables are built with points already negated, so no need here. */ + ep8_sub(q, r, t[i][0]); + fp8_copy_sec(r->x, q->x, b[i]); + fp8_copy_sec(r->y, q->y, b[i]); + fp8_copy_sec(r->z, q->z, b[i]); + } + + /* Convert r to affine coordinates. */ + ep8_norm(r, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + ep8_free(q); + ep8_free(w); + for (int i = 0; i < 16; i++) { + bn_free(_k[i]); + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + ep8_free(t[i][j]); + } + } } } +#endif /* EP_MUL == LWREG */ #endif /* EP_ENDOM */ #if defined(EP_PLAIN) || defined(EP_SUPER) +#if EP_MUL == LWNAF || !defined(STRIP) + static void ep8_mul_naf_imp(ep8_t r, const ep8_t p, const bn_t k) { int i, n; int8_t naf[RLC_FP_BITS + 1]; @@ -162,9 +284,95 @@ static void ep8_mul_naf_imp(ep8_t r, const ep8_t p, const bn_t k) { } } -#endif /* EP_PLAIN || EP_SUPER */ #endif /* EP_MUL == LWNAF */ +#if EP_MUL == LWREG || !defined(STRIP) + +static void ep8_mul_reg_imp(ep8_t r, const ep8_t p, const bn_t k) { + bn_t _k; + int8_t s, reg[1 + RLC_CEIL(RLC_FP_BITS + 1, RLC_WIDTH - 1)]; + ep8_t t[1 << (RLC_WIDTH - 2)], u, v; + size_t l, n; + + bn_null(_k); + + RLC_TRY { + bn_new(_k); + ep8_new(u); + ep8_new(v); + /* Prepare the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep8_null(t[i]); + ep8_new(t[i]); + } + /* Compute the precomputation table. */ + ep8_tab(t, p, RLC_WIDTH); + + ep8_curve_get_ord(_k); + n = bn_bits(_k); + + /* Make a copy of the scalar for processing. */ + bn_abs(_k, k); + _k->dp[0] |= 1; + + /* Compute the regular w-NAF representation of k. */ + l = RLC_CEIL(n, RLC_WIDTH - 1) + 1; + bn_rec_reg(reg, &l, _k, n, RLC_WIDTH); + +#if defined(EP_MIXED) + fp8_set_dig(u->z, 1); + u->coord = BASIC; +#else + u->coord = EP_ADD; +#endif + ep8_set_infty(r); + for (int i = l - 1; i >= 0; i--) { + for (size_t j = 0; j < RLC_WIDTH - 1; j++) { + ep8_dbl(r, r); + } + + n = reg[i]; + s = (n >> 7); + n = ((n ^ s) - s) >> 1; + + for (size_t j = 0; j < (1 << (RLC_WIDTH - 2)); j++) { + fp8_copy_sec(u->x, t[j]->x, j == n); + fp8_copy_sec(u->y, t[j]->y, j == n); +#if !defined(EP_MIXED) + fp_copy_sec(u->z, t[j]->z, j == n); +#endif + } + ep8_neg(v, u); + fp8_copy_sec(u->y, v->y, s != 0); + ep8_add(r, r, u); + } + /* t[0] has an unmodified copy of p. */ + ep8_sub(u, r, t[0]); + fp8_copy_sec(r->x, u->x, bn_is_even(k)); + fp8_copy_sec(r->y, u->y, bn_is_even(k)); + fp8_copy_sec(r->z, u->z, bn_is_even(k)); + /* Convert r to affine coordinates. */ + ep8_norm(r, r); + ep8_neg(u, r); + fp8_copy_sec(r->y, u->y, bn_sign(k) == RLC_NEG); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + /* Free the precomputation table. */ + for (size_t i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + ep8_free(t[i]); + } + bn_free(_k); + ep8_free(u); + ep8_free(v); + } +} + +#endif /* EP_MUL == LWREG */ +#endif /* EP_PLAIN || EP_SUPER */ + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -327,7 +535,7 @@ void ep8_mul_monty(ep8_t r, const ep8_t p, const bn_t k) { bn_abs(l, _k); bn_add(l, l, n); bn_add(n, l, n); - dv_swap_cond(l->dp, n->dp, RLC_MAX(l->used, n->used), + dv_swap_sec(l->dp, n->dp, RLC_MAX(l->used, n->used), bn_get_bit(l, bits) == 0); l->used = RLC_SEL(l->used, n->used, bn_get_bit(l, bits) == 0); @@ -343,9 +551,9 @@ void ep8_mul_monty(ep8_t r, const ep8_t p, const bn_t k) { for (int l = 0; l < 2; l++) { for (int m = 0; m < 2; m++) { for (int n = 0; n < 2; n++) { - dv_swap_cond(t[0]->x[l][m][n], t[1]->x[l][m][n], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[l][m][n], t[1]->y[l][m][n], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[l][m][n], t[1]->z[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[l][m][n], t[1]->x[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[l][m][n], t[1]->y[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[l][m][n], t[1]->z[l][m][n], RLC_FP_DIGS, j ^ 1); } } } @@ -354,9 +562,9 @@ void ep8_mul_monty(ep8_t r, const ep8_t p, const bn_t k) { for (int l = 0; l < 2; l++) { for (int m = 0; m < 2; m++) { for (int n = 0; n < 2; n++) { - dv_swap_cond(t[0]->x[l][m][n], t[1]->x[l][m][n], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->y[l][m][n], t[1]->y[l][m][n], RLC_FP_DIGS, j ^ 1); - dv_swap_cond(t[0]->z[l][m][n], t[1]->z[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->x[l][m][n], t[1]->x[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->y[l][m][n], t[1]->y[l][m][n], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0]->z[l][m][n], t[1]->z[l][m][n], RLC_FP_DIGS, j ^ 1); } } } @@ -399,6 +607,28 @@ void ep8_mul_lwnaf(ep8_t r, const ep8_t p, const bn_t k) { #endif +#if EP_MUL == LWREG || !defined(STRIP) + +void ep8_mul_lwreg(ep8_t r, const ep8_t p, const bn_t k) { + if (bn_is_zero(k) || ep8_is_infty(p)) { + ep8_set_infty(r); + return; + } + +#if defined(EP_ENDOM) + if (ep_curve_is_endom()) { + ep8_mul_reg_gls(r, p, k); + return; + } +#endif + +#if defined(EP_PLAIN) || defined(EP_SUPER) + ep8_mul_reg_imp(r, p, k); +#endif +} + +#endif + void ep8_mul_gen(ep8_t r, const bn_t k) { if (bn_is_zero(k)) { ep8_set_infty(r); diff --git a/src/epx/relic_ep8_mul_cof.c b/src/epx/relic_ep8_mul_cof.c index 65f85a660..2d43beef6 100644 --- a/src/epx/relic_ep8_mul_cof.c +++ b/src/epx/relic_ep8_mul_cof.c @@ -25,14 +25,13 @@ * @file * * Implementation of point multiplication of a prime elliptic curve over an - * octic extension by the curve cofactor. + * octic extension field by the curve cofactor. * * @ingroup epx */ #include "relic_core.h" #include "relic_md.h" -#include "relic_tmpl_map.h" /*============================================================================*/ /* Public definitions */ diff --git a/src/epx/relic_ep8_mul_fix.c b/src/epx/relic_ep8_mul_fix.c index 94e80748e..f11327a91 100644 --- a/src/epx/relic_ep8_mul_fix.c +++ b/src/epx/relic_ep8_mul_fix.c @@ -25,7 +25,7 @@ * @file * * Implementation of fixed point multiplication on a prime elliptic curve over - * a quartic extension. + * an octic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep8_mul_sim.c b/src/epx/relic_ep8_mul_sim.c index db08c8cbc..e6febc105 100644 --- a/src/epx/relic_ep8_mul_sim.c +++ b/src/epx/relic_ep8_mul_sim.c @@ -25,7 +25,7 @@ * @file * * Implementation of simultaneous point multiplication on a prime elliptic - * curve over a quartic extension. + * curve over an octic extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep8_neg.c b/src/epx/relic_ep8_neg.c index 3f0f3061e..accaa0670 100644 --- a/src/epx/relic_ep8_neg.c +++ b/src/epx/relic_ep8_neg.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point negation on elliptic prime curves over quartic - * extensions. + * Implementation of point negation on elliptic prime curves over an octic + * extension field. * * @ingroup epx */ diff --git a/src/epx/relic_ep8_norm.c b/src/epx/relic_ep8_norm.c index a477299b2..a70382332 100644 --- a/src/epx/relic_ep8_norm.c +++ b/src/epx/relic_ep8_norm.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of point normalization on prime elliptic curves over octic - * extensions. + * Implementation of point normalization on prime elliptic curves over an octic + * extension field. * * @ingroup epx */ @@ -43,36 +43,45 @@ * * @param r - the result. * @param p - the point to normalize. + * @param inv - the flag to indicate if z is already inverted. */ -static void ep8_norm_imp(ep8_t r, const ep8_t p, int inverted) { +static void ep8_norm_imp(ep8_t r, const ep8_t p, int inv) { if (p->coord != BASIC) { - fp8_t t0, t1; + fp8_t t; - fp8_null(t0); - fp8_null(t1); + fp8_null(t); RLC_TRY { + fp8_new(t); - fp8_new(t0); - fp8_new(t1); - - if (inverted) { - fp8_copy(t1, p->z); + if (inv) { + fp8_copy(r->z, p->z); } else { - fp8_inv(t1, p->z); + fp8_inv(r->z, p->z); + } + + switch (p->coord) { + case PROJC: + fp8_mul(r->x, p->x, r->z); + fp8_mul(r->y, p->y, r->z); + break; + case JACOB: + fp8_sqr(t, r->z); + fp8_mul(r->x, p->x, t); + fp8_mul(t, t, r->z); + fp8_mul(r->y, p->y, t); + break; + default: + ep8_copy(r, p); + break; } - fp8_sqr(t0, t1); - fp8_mul(r->x, p->x, t0); - fp8_mul(t0, t0, t1); - fp8_mul(r->y, p->y, t0); fp8_set_dig(r->z, 1); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { - fp8_free(t0); - fp8_free(t1); + fp8_free(t); } } @@ -92,17 +101,18 @@ void ep8_norm(ep8_t r, const ep8_t p) { } if (p->coord == BASIC) { - /* If the point is represented in affine coordinates, we just copy it. */ + /* If the point is represented in affine coordinates, just copy it. */ ep8_copy(r, p); + return; } -#if EP_ADD == PROJC || !defined(STRIP) +#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) ep8_norm_imp(r, p, 0); -#endif +#endif /* EP_ADD == PROJC */ } void ep8_norm_sim(ep8_t *r, const ep8_t *t, int n) { int i; - fp8_t *a = RLC_ALLOCA(fp8_t, n); + fp8_t* a = RLC_ALLOCA(fp8_t, n); RLC_TRY { if (a == NULL) { @@ -114,17 +124,20 @@ void ep8_norm_sim(ep8_t *r, const ep8_t *t, int n) { fp8_copy(a[i], t[i]->z); } - fp8_inv_sim(a, a, n); + fp8_inv_sim(a, (const fp8_t *)a, n); for (i = 0; i < n; i++) { fp8_copy(r[i]->x, t[i]->x); fp8_copy(r[i]->y, t[i]->y); - fp8_copy(r[i]->z, a[i]); + if (!ep8_is_infty(t[i])) { + fp8_copy(r[i]->z, a[i]); + } } - +#if EP_ADD == PROJC || EP_ADD == JACOB || !defined(STRIP) for (i = 0; i < n; i++) { ep8_norm_imp(r[i], r[i], 1); } +#endif /* EP_ADD == PROJC */ } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/epx/relic_ep8_util.c b/src/epx/relic_ep8_util.c index 3b5e737f0..0c44ff045 100644 --- a/src/epx/relic_ep8_util.c +++ b/src/epx/relic_ep8_util.c @@ -24,8 +24,8 @@ /** * @file * - * Implementation of comparison for points on prime elliptic curves over - * quartic extensions. + * Implementation of comparison for points on prime elliptic curves over an + * octic extensions. * * @ingroup epx */ @@ -89,13 +89,18 @@ void ep8_blind(ep8_t r, const ep8_t p) { #if EP_ADD == BASIC (void)rand; ep8_copy(r, p); -#else +#elif EP_ADD == PROJC + fp8_mul(r->x, p->x, rand); + fp8_mul(r->y, p->y, rand); + fp8_mul(r->z, p->z, rand); + r->coord = PROJC; +#elif EP_ADD == JACOB fp8_mul(r->z, p->z, rand); fp8_mul(r->y, p->y, rand); fp8_sqr(rand, rand); fp8_mul(r->x, r->x, rand); fp8_mul(r->y, r->y, rand); - r->coord = EP_ADD; + r->coord = JACOB; #endif } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -104,17 +109,15 @@ void ep8_blind(ep8_t r, const ep8_t p) { } } -void ep8_rhs(fp8_t rhs, const ep8_t p) { - fp8_t t0, t1; +void ep8_rhs(fp8_t rhs, const fp8_t x) { + fp8_t t0; fp8_null(t0); - fp8_null(t1); RLC_TRY { fp8_new(t0); - fp8_new(t1); - fp8_sqr(t0, p->x); /* x1^2 */ + fp8_sqr(t0, x); switch (ep8_curve_opt_a()) { case RLC_ZERO: @@ -130,24 +133,16 @@ void ep8_rhs(fp8_t rhs, const ep8_t p) { fp_add_dig(t0[0][0][0], t0[0][0][0], 2); break; case RLC_TINY: - ep8_curve_get_a(t1); - fp_mul_dig(t0[0][0][0], t0[0][0][0], t1[0][0][0][0]); - fp_mul_dig(t0[0][0][1], t0[0][0][1], t1[0][0][0][0]); - fp_mul_dig(t0[0][1][0], t0[0][1][0], t1[0][0][0][0]); - fp_mul_dig(t0[0][1][1], t0[0][1][1], t1[0][0][0][0]); - fp_mul_dig(t0[1][0][0], t0[1][0][0], t1[0][0][0][0]); - fp_mul_dig(t0[1][0][1], t0[1][0][1], t1[0][0][0][0]); - fp_mul_dig(t0[1][1][0], t0[1][1][0], t1[0][0][0][0]); - fp_mul_dig(t0[1][1][1], t0[1][1][1], t1[0][0][0][0]); + fp_add_dig(t0[0][0][0], t0[0][0][0], + ep8_curve_get_a()[0][0][0][0]); break; #endif default: - ep8_curve_get_a(t1); - fp8_add(t0, t0, t1); + fp8_add(t0, t0, ep8_curve_get_a()); break; } - fp8_mul(t0, t0, p->x); /* x1^3 + a * x */ + fp8_mul(t0, t0, x); switch (ep8_curve_opt_b()) { case RLC_ZERO: @@ -163,16 +158,12 @@ void ep8_rhs(fp8_t rhs, const ep8_t p) { fp_add_dig(t0[0][0][0], t0[0][0][0], 2); break; case RLC_TINY: - ep8_curve_get_b(t1); - fp_mul_dig(t0[0][0][0], t0[0][0][0], t1[0][0][0][0]); - fp_mul_dig(t0[0][1][0], t0[0][1][0], t1[0][0][0][0]); - fp_mul_dig(t0[1][0][0], t0[0][0][0], t1[0][0][0][0]); - fp_mul_dig(t0[1][1][0], t0[1][1][0], t1[0][0][0][0]); + fp_add_dig(t0[0][0][0], t0[0][0][0], + ep8_curve_get_b()[0][0][0][0]); break; #endif default: - ep8_curve_get_b(t1); - fp8_add(t0, t0, t1); + fp8_add(t0, t0, ep8_curve_get_b()); break; } @@ -181,11 +172,9 @@ void ep8_rhs(fp8_t rhs, const ep8_t p) { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { fp8_free(t0); - fp8_free(t1); } } - int ep8_on_curve(const ep8_t p) { ep8_t t; int r = 0; @@ -197,7 +186,7 @@ int ep8_on_curve(const ep8_t p) { ep8_norm(t, p); - ep8_rhs(t->x, t); + ep8_rhs(t->x, t->x); fp8_sqr(t->y, t->y); r = (fp8_cmp(t->x, t->y) == RLC_EQ) || ep8_is_infty(p); @@ -321,8 +310,8 @@ void ep8_write_bin(uint8_t *bin, size_t len, const ep8_t a, int pack) { RLC_THROW(ERR_NO_BUFFER); } else { bin[0] = 4; - fp8_write_bin(bin + 1, 8 * RLC_FP_BYTES, t->x); - fp8_write_bin(bin + 8 * RLC_FP_BYTES + 1, 8 * RLC_FP_BYTES, t->y); + fp8_write_bin(bin + 1, 8 * RLC_FP_BYTES, t->x, 0); + fp8_write_bin(bin + 8 * RLC_FP_BYTES + 1, 8 * RLC_FP_BYTES, t->y, 0); } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/fb/relic_fb_cmp.c b/src/fb/relic_fb_cmp.c index 9e3dc2085..3eb0ef1b8 100644 --- a/src/fb/relic_fb_cmp.c +++ b/src/fb/relic_fb_cmp.c @@ -48,5 +48,5 @@ int fb_cmp_dig(const fb_t a, dig_t b) { } int fb_cmp(const fb_t a, const fb_t b) { - return dv_cmp_const(a, b, RLC_FB_DIGS); + return dv_cmp_sec(a, b, RLC_FB_DIGS); } diff --git a/src/fb/relic_fb_exp.c b/src/fb/relic_fb_exp.c index 600287306..b25d688a9 100644 --- a/src/fb/relic_fb_exp.c +++ b/src/fb/relic_fb_exp.c @@ -173,10 +173,10 @@ void fb_exp_monty(fb_t c, const fb_t a, const bn_t b) { for (int i = bn_bits(b) - 1; i >= 0; i--) { int j = bn_get_bit(b, i); - dv_swap_cond(t[0], t[1], RLC_FB_DIGS, j ^ 1); + dv_swap_sec(t[0], t[1], RLC_FB_DIGS, j ^ 1); fb_mul(t[0], t[0], t[1]); fb_sqr(t[1], t[1]); - dv_swap_cond(t[0], t[1], RLC_FB_DIGS, j ^ 1); + dv_swap_sec(t[0], t[1], RLC_FB_DIGS, j ^ 1); } if (bn_sign(b) == RLC_NEG) { diff --git a/src/fp/relic_fp_crt.c b/src/fp/relic_fp_crt.c index 140f64683..74e5326f3 100644 --- a/src/fp/relic_fp_crt.c +++ b/src/fp/relic_fp_crt.c @@ -157,7 +157,7 @@ int fp_crt(fp_t c, const fp_t a) { fp_exp(t0, a, e); /* Recover 3^f-root of unity, and continue algorithm. */ - fp_copy(t3, fp_prime_get_crt()); + fp_copy(t3, (const dig_t *)fp_prime_get_crt()); fp_copy(c, t3); for (int i = 0; i < f - 1; i++) { diff --git a/src/fp/relic_fp_exp.c b/src/fp/relic_fp_exp.c index de847ba78..715dc55dc 100644 --- a/src/fp/relic_fp_exp.c +++ b/src/fp/relic_fp_exp.c @@ -168,10 +168,10 @@ void fp_exp_monty(fp_t c, const fp_t a, const bn_t b) { for (int i = bn_bits(b) - 1; i >= 0; i--) { int j = bn_get_bit(b, i); - dv_swap_cond(t[0], t[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0], t[1], RLC_FP_DIGS, j ^ 1); fp_mul(t[0], t[0], t[1]); fp_sqr(t[1], t[1]); - dv_swap_cond(t[0], t[1], RLC_FP_DIGS, j ^ 1); + dv_swap_sec(t[0], t[1], RLC_FP_DIGS, j ^ 1); } if (bn_sign(b) == RLC_NEG) { diff --git a/src/fp/relic_fp_inv.c b/src/fp/relic_fp_inv.c index 91615ede3..4ca9b265b 100644 --- a/src/fp/relic_fp_inv.c +++ b/src/fp/relic_fp_inv.c @@ -512,10 +512,10 @@ void fp_inv_divst(fp_t c, const fp_t a) { /* Conditionally negate delta if d0 is set. */ delta = (delta ^ -d0) + d0; /* Conditionally swap based on d0. */ - dv_swap_cond(r, v, RLC_FP_DIGS, d0); + dv_swap_sec(r, v, RLC_FP_DIGS, d0); fp_negm_low(t, r); - dv_swap_cond(f, g, RLC_FP_DIGS, d0); - dv_copy_cond(r, t, RLC_FP_DIGS, d0); + dv_swap_sec(f, g, RLC_FP_DIGS, d0); + dv_copy_sec(r, t, RLC_FP_DIGS, d0); for (int j = 0; j < RLC_FP_DIGS; j++) { g[j] = RLC_SEL(g[j], ~g[j], d0); } @@ -541,7 +541,7 @@ void fp_inv_divst(fp_t c, const fp_t a) { g[RLC_FP_DIGS - 1] |= (dig_t)gs << (RLC_DIG - 1); } fp_neg(t, v); - dv_copy_cond(v, t, RLC_FP_DIGS, fs); + fp_copy_sec(v, t, fs); dv_copy(t, fp_prime_get(), RLC_FP_DIGS); fp_add_dig(t, t, 1); @@ -650,10 +650,10 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Update column vector below. */ v1[0] = RLC_SEL(m[1], -m[1], RLC_SIGN(m[1])); fp_negm_low(t, v1); - dv_copy_cond(v1, t, RLC_FP_DIGS, RLC_SIGN(m[1])); + fp_copy_sec(v1, t, RLC_SIGN(m[1])); u1[0] = RLC_SEL(m[3], -m[3], RLC_SIGN(m[3])); fp_negm_low(t, u1); - dv_copy_cond(u1, t, RLC_FP_DIGS, RLC_SIGN(m[3])); + fp_copy_sec(u1, t, RLC_SIGN(m[3])); dv_copy(p01, v1, 2 * RLC_FP_DIGS); dv_copy(p11, u1, 2 * RLC_FP_DIGS); @@ -686,19 +686,19 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Update column vector below. */ bn_mul2_low(v0, p01, m[0], RLC_FP_DIGS + j); fp_subd_low(t, p, v0); - dv_copy_cond(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); + dv_copy_sec(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); bn_mul2_low(v1, p11, m[1], RLC_FP_DIGS + j); fp_subd_low(t, p, v1); - dv_copy_cond(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); + dv_copy_sec(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); bn_mul2_low(u0, p01, m[2], RLC_FP_DIGS + j); fp_subd_low(t, p, u0); - dv_copy_cond(u0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[2])); + dv_copy_sec(u0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[2])); bn_mul2_low(u1, p11, m[3], RLC_FP_DIGS + j); fp_subd_low(t, p, u1); - dv_copy_cond(u1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[3])); + dv_copy_sec(u1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[3])); j = i % RLC_FP_DIGS; if (j == 0) { @@ -719,19 +719,19 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Update column vector below. */ bn_mul2_low(v0, p01, m[0], 2 * RLC_FP_DIGS); fp_subd_low(t, p, v0); - dv_copy_cond(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); + dv_copy_sec(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); bn_mul2_low(v1, p11, m[1], 2 * RLC_FP_DIGS); fp_subd_low(t, p, v1); - dv_copy_cond(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); + dv_copy_sec(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); bn_mul2_low(u0, p01, m[2], 2 * RLC_FP_DIGS); fp_subd_low(t, p, u0); - dv_copy_cond(u0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[2])); + dv_copy_sec(u0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[2])); bn_mul2_low(u1, p11, m[3], 2 * RLC_FP_DIGS); fp_subd_low(t, p, u1); - dv_copy_cond(u1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[3])); + dv_copy_sec(u1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[3])); fp_addc_low(t, u0, u1); fp_rdc(p11, t); @@ -768,11 +768,11 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Update column vector below. */ bn_mul2_low(v0, p01, m[0], RLC_FP_DIGS + j); fp_subd_low(t, p, v0); - dv_copy_cond(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); + dv_copy_sec(v0, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[0])); bn_mul2_low(v1, p11, m[1], RLC_FP_DIGS + j); fp_subd_low(t, p, v1); - dv_copy_cond(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); + dv_copy_sec(v1, t, RLC_FP_DIGS + j + 1, RLC_SIGN(m[1])); fp_addd_low(t, v0, v1); fp_rdc(p01, t); @@ -784,11 +784,11 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Update column vector below. */ bn_mul2_low(v0, p01, m[0], 2 * RLC_FP_DIGS); fp_subd_low(t, p, v0); - dv_copy_cond(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); + dv_copy_sec(v0, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[0])); bn_mul2_low(v1, p11, m[1], 2 * RLC_FP_DIGS); fp_subd_low(t, p, v1); - dv_copy_cond(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); + dv_copy_sec(v1, t, 2 * RLC_FP_DIGS, RLC_SIGN(m[1])); fp_addc_low(t, v0, v1); fp_rdc(p01, t); @@ -796,7 +796,7 @@ void fp_inv_jmpds(fp_t c, const fp_t a) { /* Negate based on sign of f at the end. */ fp_negm_low(t, p01); - dv_copy_cond(p01, t, RLC_FP_DIGS, f[RLC_FP_DIGS] >> (RLC_DIG - 1)); + dv_copy_sec(p01, t, RLC_FP_DIGS, f[RLC_FP_DIGS] >> (RLC_DIG - 1)); /* Multiply by (precomp * R^j) % p, one for each iteration of the loop, * one for the constant, one more to be removed by reduction. */ diff --git a/src/fp/relic_fp_param.c b/src/fp/relic_fp_param.c index 674ffb3de..8ff841371 100644 --- a/src/fp/relic_fp_param.c +++ b/src/fp/relic_fp_param.c @@ -569,16 +569,6 @@ void fp_param_set(int param) { fp_prime_set_pairf(t0, EP_SG18); break; #elif FP_PRIME == 765 - case N16_765: - /* u = -(2^48 - 2^44 + 2^37) */ - bn_set_2b(t0, 48); - bn_set_2b(t1, 44); - bn_sub(t0, t0, t1); - bn_set_2b(t1, 37); - bn_add(t0, t0, t1); - bn_neg(t0, t0); - fp_prime_set_pairf(t0, EP_N16); - break; case FM16_765: /* u = 2^48-2^44-2^38+2^31 */ bn_set_2b(t0, 48); @@ -605,13 +595,13 @@ void fp_param_set(int param) { fp_prime_set_pairf(t0, EP_K16); break; case N16_766: - /* u = 2^48-2^20+2^15+2^5 */ + /* u = 2^48-2^28-2^25+2^2 */ bn_set_2b(t0, 48); - bn_set_2b(t1, 20); + bn_set_2b(t1, 28); bn_sub(t0, t0, t1); - bn_set_2b(t1, 15); - bn_add(t0, t0, t1); - bn_add_dig(t0, t0, 32); + bn_set_2b(t1, 25); + bn_sub(t0, t0, t1); + bn_add_dig(t0, t0, 4); fp_prime_set_pairf(t0, EP_N16); break; #elif FP_PRIME == 768 @@ -633,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. */ @@ -821,13 +827,14 @@ int fp_param_set_any_tower(void) { //fp_param_set(SG18_638); #endif #elif FP_PRIME == 765 - fp_param_set(N16_765); - //fp_param_set(FM16_765); + fp_param_set(FM16_765); #elif FP_PRIME == 766 fp_param_set(N16_766); //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/fp/relic_fp_smb.c b/src/fp/relic_fp_smb.c index be7973591..bdab95d3d 100644 --- a/src/fp/relic_fp_smb.c +++ b/src/fp/relic_fp_smb.c @@ -208,7 +208,7 @@ int fp_smb_divst(const fp_t a) { #endif r = dv_cmp(g, f, RLC_FP_DIGS); fp_subn_low(t, g, f); - dv_copy_cond(g, t, RLC_FP_DIGS, r != RLC_LT); + fp_copy_sec(g, t, r != RLC_LT); fs = gs = RLC_POS; @@ -251,9 +251,9 @@ int fp_smb_divst(const fp_t a) { t[0] = 1; bn_negs_low(f, f, fs, RLC_FP_DIGS); - r = RLC_SEL(r, 1 - k, dv_cmp_const(f, t, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - k, dv_cmp_sec(f, t, RLC_FP_DIGS) == RLC_EQ); bn_negs_low(t, t, 1, RLC_FP_DIGS); - r = RLC_SEL(r, 1 - k, dv_cmp_const(f, t, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - k, dv_cmp_sec(f, t, RLC_FP_DIGS) == RLC_EQ); r = RLC_SEL(r, 1 - k, fp_is_zero(f)); r = RLC_SEL(r, 0, fp_is_zero(a)); } RLC_CATCH_ANY { @@ -350,11 +350,11 @@ int fp_smb_jmpds(const fp_t a) { j = (j + (j & 1)) % 4; fp_zero(t0); - r = RLC_SEL(r, 1 - j, dv_cmp_const(f, t0, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - j, dv_cmp_sec(f, t0, RLC_FP_DIGS) == RLC_EQ); t0[0] = 1; - r = RLC_SEL(r, 1 - j, dv_cmp_const(f, t0, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - j, dv_cmp_sec(f, t0, RLC_FP_DIGS) == RLC_EQ); bn_negs_low(t0, t0, 1, RLC_FP_DIGS); - r = RLC_SEL(r, 1 - j, dv_cmp_const(f, t0, RLC_FP_DIGS) == RLC_EQ); + r = RLC_SEL(r, 1 - j, dv_cmp_sec(f, t0, RLC_FP_DIGS) == RLC_EQ); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); diff --git a/src/fp/relic_fp_srt.c b/src/fp/relic_fp_srt.c index c5656be1c..693fd99a9 100644 --- a/src/fp/relic_fp_srt.c +++ b/src/fp/relic_fp_srt.c @@ -110,16 +110,14 @@ int fp_srt(fp_t c, const fp_t a) { fp_sqr(t2, t2); } fp_mul(t0, c, t3); - dv_copy_cond(c, t0, RLC_FP_DIGS, - fp_cmp_dig(t2, 1) != RLC_EQ); + fp_copy_sec(c, t0, fp_cmp_dig(t2, 1) != RLC_EQ); fp_sqr(t3, t3); fp_mul(t0, t1, t3); - dv_copy_cond(t1, t0, RLC_FP_DIGS, - fp_cmp_dig(t2, 1) != RLC_EQ); + fp_copy_sec(t1, t0, fp_cmp_dig(t2, 1) != RLC_EQ); } fp_neg(t0, c); - dv_copy_cond(c, t0, RLC_FP_DIGS, fp_is_even(c) == 0); + fp_copy_sec(c, t0, fp_is_even(c) == 0); break; } } diff --git a/src/fp/relic_fp_util.c b/src/fp/relic_fp_util.c index 8866fbb43..9556a9fd8 100644 --- a/src/fp/relic_fp_util.c +++ b/src/fp/relic_fp_util.c @@ -40,6 +40,10 @@ void fp_copy(fp_t c, const fp_t a) { dv_copy(c, a, RLC_FP_DIGS); } +void fp_copy_sec(fp_t c, const fp_t a, dig_t bit) { + dv_copy_sec(c, a, RLC_FP_DIGS, bit); +} + void fp_zero(fp_t a) { dv_zero(a, RLC_FP_DIGS); } diff --git a/src/fpx/relic_fp2_mul.c b/src/fpx/relic_fp2_mul.c index 558f8b0f7..457e8724b 100644 --- a/src/fpx/relic_fp2_mul.c +++ b/src/fpx/relic_fp2_mul.c @@ -121,17 +121,20 @@ void fp2_mul_nor_basic(fp2_t c, const fp2_t a) { int qnr = fp2_field_get_qnr(); switch (fp_prime_get_mod8()) { - case 3: - /* If p = 3 mod 8, (1 + i) is a QNR/CNR. */ - fp_neg(t[0], a[1]); - fp_add(c[1], a[0], a[1]); - fp_add(c[0], t[0], a[0]); - break; case 1: case 5: /* If p = 1,5 mod 8, (i) is a QNR/CNR. */ fp2_mul_art(c, a); break; + case 3: + if (qnr == 1) { + /* If p = 3 mod 8, (1 + i) is a QNR/CNR. */ + fp_neg(t[0], a[1]); + fp_add(c[1], a[0], a[1]); + fp_add(c[0], t[0], a[0]); + break; + } + /* Otherwise, fall back to next one. */ case 7: /* If p = 7 mod 8, we choose (2^k + i) as a QNR/CNR. */ fp2_mul_art(t, a); diff --git a/src/fpx/relic_fp8_mul.c b/src/fpx/relic_fp8_mul.c index c2d0587da..878d2d7a3 100644 --- a/src/fpx/relic_fp8_mul.c +++ b/src/fpx/relic_fp8_mul.c @@ -298,3 +298,8 @@ void fp8_mul_frb(fp8_t c, const fp8_t a, int i, int j) { fp4_free(t); } } + +void fp8_mul_dig(fp8_t c, const fp8_t a, dig_t b) { + fp4_mul_dig(c[0], a[0], b); + fp4_mul_dig(c[1], a[1], b); +} diff --git a/src/fpx/relic_fpx_cyc.c b/src/fpx/relic_fpx_cyc.c index 02803b6c9..f1b9acbbf 100644 --- a/src/fpx/relic_fpx_cyc.c +++ b/src/fpx/relic_fpx_cyc.c @@ -368,6 +368,108 @@ void fp8_exp_cyc(fp8_t c, const fp8_t a, const bn_t b) { } } +void fp8_exp_cyc_sim(fp8_t e, const fp8_t a, const bn_t b, const fp8_t c, + const bn_t d) { + int n0, n1; + int8_t naf0[RLC_FP_BITS + 1], naf1[RLC_FP_BITS + 1], *_k, *_m; + fp8_t r, t0[1 << (RLC_WIDTH - 2)]; + fp8_t s, t1[1 << (RLC_WIDTH - 2)]; + size_t l, l0, l1; + + if (bn_is_zero(b)) { + return fp8_exp_cyc(e, c, d); + } + + if (bn_is_zero(d)) { + return fp8_exp_cyc(e, a, b); + } + + fp8_null(r); + fp8_null(s); + + RLC_TRY { + fp8_new(r); + fp8_new(s); + for (int i = 0; i < (1 << (RLC_WIDTH - 2)); i ++) { + fp8_null(t0[i]); + fp8_null(t1[i]); + fp8_new(t0[i]); + fp8_new(t1[i]); + } + +#if RLC_WIDTH > 2 + fp8_sqr(t0[0], a); + fp8_mul(t0[1], t0[0], a); + for (int i = 2; i < (1 << (RLC_WIDTH - 2)); i++) { + fp8_mul(t0[i], t0[i - 1], t0[0]); + } + + fp8_sqr(t1[0], c); + fp8_mul(t1[1], t1[0], c); + for (int i = 2; i < (1 << (RLC_WIDTH - 2)); i++) { + fp8_mul(t1[i], t1[i - 1], t1[0]); + } +#endif + fp8_copy(t0[0], a); + fp8_copy(t1[0], c); + + l0 = l1 = RLC_FP_BITS + 1; + bn_rec_naf(naf0, &l0, b, RLC_WIDTH); + bn_rec_naf(naf1, &l1, d, RLC_WIDTH); + + l = RLC_MAX(l0, l1); + if (bn_sign(b) == RLC_NEG) { + for (size_t i = 0; i < l0; i++) { + naf0[i] = -naf0[i]; + } + } + if (bn_sign(d) == RLC_NEG) { + for (size_t i = 0; i < l1; i++) { + naf1[i] = -naf1[i]; + } + } + + _k = naf0 + l - 1; + _m = naf1 + l - 1; + + fp8_set_dig(r, 1); + for (int i = l - 1; i >= 0; i--, _k--, _m--) { + fp8_sqr(r, r); + + n0 = *_k; + n1 = *_m; + + if (n0 > 0) { + fp8_mul(r, r, t0[n0 / 2]); + } + if (n0 < 0) { + fp8_inv_cyc(s, t0[-n0 / 2]); + fp8_mul(r, r, s); + } + if (n1 > 0) { + fp8_mul(r, r, t1[n1 / 2]); + } + if (n1 < 0) { + fp8_inv_cyc(s, t1[-n1 / 2]); + fp8_mul(r, r, s); + } + } + + fp8_copy(e, r); + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + fp8_free(r); + fp8_free(s); + for (int i = 0; i < (1 << (RLC_WIDTH - 2)); i++) { + fp8_free(t0[i]); + fp8_free(t1[i]); + } + } +} + void fp12_conv_cyc(fp12_t c, const fp12_t a) { fp12_t t; @@ -443,13 +545,11 @@ void fp12_back_cyc(fp12_t c, const fp12_t a) { int f = fp2_is_zero(a[1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp2_copy(t2, a[0][1]); - dv_copy_cond(t2[0], a[1][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[1], a[1][2][1], RLC_FP_DIGS, f); + fp2_copy_sec(t2, a[1][2], f); /* t0 = g4^2. */ fp2_mul(t0, a[0][1], t2); fp2_dbl(t2, t0); - dv_copy_cond(t0[0], t2[0], RLC_FP_DIGS, f); - dv_copy_cond(t0[1], t2[1], RLC_FP_DIGS, f); + fp2_copy_sec(t0, t2, f); /* t1 = 3 * g4^2 - 2 * g3. */ fp2_sub(t1, t0, a[0][2]); fp2_dbl(t1, t1); @@ -461,13 +561,11 @@ void fp12_back_cyc(fp12_t c, const fp12_t a) { /* t1 = (4 * g2). */ fp2_dbl(t1, a[1][0]); fp2_dbl(t1, t1); - dv_copy_cond(t1[0], a[0][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1], a[0][2][1], RLC_FP_DIGS, f); + fp2_copy_sec(t1, a[0][2], f); /* If unity, decompress to unity as well. */ f = fp12_cmp_dig(a, 1) == RLC_EQ; fp2_set_dig(t2, 1); - dv_copy_cond(t1[0], t2[0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1], t2[1], RLC_FP_DIGS, f); + fp2_copy_sec(t1, t2, f); /* t1 = 1/g3 or 1/(4*g2), depending on the above. */ fp2_inv(t1, t1); @@ -529,13 +627,11 @@ void fp12_back_cyc_sim(fp12_t c[], const fp12_t a[], int n) { int f = fp2_is_zero(a[i][1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp2_copy(t2[i], a[i][0][1]); - dv_copy_cond(t2[i][0], a[i][1][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1], a[i][1][2][1], RLC_FP_DIGS, f); + fp2_copy_sec(t2[i], a[i][1][2], f); /* t0 = g4^2. */ fp2_mul(t0[i], a[i][0][1], t2[i]); fp2_dbl(t2[i], t0[i]); - dv_copy_cond(t0[i][0], t2[i][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1], t2[i][1], RLC_FP_DIGS, f); + fp2_copy_sec(t0[i], t2[i], f); /* t1 = 3 * g4^2 - 2 * g3. */ fp2_sub(t1[i], t0[i], a[i][0][2]); fp2_dbl(t1[i], t1[i]); @@ -547,13 +643,11 @@ void fp12_back_cyc_sim(fp12_t c[], const fp12_t a[], int n) { /* t1 = (4 * g2). */ fp2_dbl(t1[i], a[i][1][0]); fp2_dbl(t1[i], t1[i]); - dv_copy_cond(t1[i][0], a[i][0][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1], a[i][0][2][1], RLC_FP_DIGS, f); + fp2_copy_sec(t1[i], a[i][0][2], f); /* If unity, decompress to unity as well. */ f = (fp12_cmp_dig(a[i], 1) == RLC_EQ); fp2_set_dig(t2[i], 1); - dv_copy_cond(t1[i][0], t2[i][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1], t2[i][1], RLC_FP_DIGS, f); + fp2_copy_sec(t1[i], t2[i], f); } /* t1 = 1 / t1. */ @@ -722,81 +816,6 @@ void fp12_exp_cyc(fp12_t c, const fp12_t a, const bn_t b) { } } -void fp12_exp_cyc_gls(fp12_t c, const fp12_t a, const bn_t b) { - size_t l, _l[4]; - int8_t naf[4][RLC_FP_BITS + 1]; - fp12_t t[4]; - bn_t _b[4], n, u; - - if (bn_is_zero(b)) { - return fp12_set_dig(c, 1); - } - - bn_null(n); - bn_null(u); - - RLC_TRY { - bn_new(n); - bn_new(u); - for (size_t i = 0; i < 4; i++) { - bn_null(_b[i]); - bn_new(_b[i]); - fp12_null(t[i]); - fp12_new(t[i]); - } - - ep_curve_get_ord(n); - fp_prime_get_par(u); - bn_abs(_b[0], b); - bn_mod(_b[0], _b[0], n); - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[0], _b[0]); - } - bn_rec_frb(_b, 4, _b[0], u, n, ep_curve_is_pairf() == EP_BN); - - fp12_copy(t[0], a); - fp12_frb(t[1], t[0], 1); - fp12_frb(t[2], t[1], 1); - fp12_frb(t[3], t[2], 1); - - l = 0; - for (size_t i = 0; i < 4; i++) { - if (bn_sign(_b[i]) == RLC_NEG) { - fp12_inv_cyc(t[i], t[i]); - } - _l[i] = RLC_FP_BITS + 1; - bn_rec_naf(naf[i], &_l[i], _b[i], 2); - l = RLC_MAX(l, _l[i]); - } - - fp12_set_dig(c, 1); - for (int i = l - 1; i >= 0; i--) { - fp12_sqr_cyc(c, c); - for (size_t j = 0; j < 4; j++) { - if (naf[j][i] > 0) { - fp12_mul(c, c, t[j]); - } - if (naf[j][i] < 0) { - fp12_inv_cyc(t[j], t[j]); - fp12_mul(c, c, t[j]); - fp12_inv_cyc(t[j], t[j]); - } - } - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(n); - bn_free(u); - for (size_t i = 0; i < 4; i++) { - bn_free(_b[i]); - fp12_free(t[i]); - } - } -} - void fp12_exp_cyc_sim(fp12_t e, const fp12_t a, const bn_t b, const fp12_t c, const bn_t d) { int i, j, l; @@ -843,7 +862,7 @@ void fp12_exp_cyc_sim(fp12_t e, const fp12_t a, const bn_t b, const fp12_t c, } bn_rec_frb(_d, 4, _d[0], x, n, ep_curve_is_pairf() == EP_BN); - if (ep_curve_is_pairf() && ep_param_embed() == 12) { + if (ep_curve_is_pairf() && ep_curve_embed() == 12) { for (i = 0; i < 4; i++) { fp12_frb(t[i], a, i); fp12_frb(u[i], c, i); @@ -1035,41 +1054,6 @@ int fp16_test_cyc(const fp16_t a) { return result; } -static void fp16_gls(fp16_t c, const fp16_t a) { - fp16_t b; - - fp16_null(b); - - RLC_TRY { - fp16_new(b); - - switch (ep_curve_is_pairf()) { - case EP_K16: - /* u = (2*p^5 - p) mod r */ - fp16_frb(b, a, 1); - fp16_frb(c, b, 4); - fp16_sqr_cyc(c, c); - fp16_inv_cyc(b, b); - fp16_mul(c, c, b); - break; - case EP_N16: - /* u = -p^5 mod r */ - fp16_frb(c, a, 5); - fp16_inv_cyc(c, c); - break; - case EP_FM16: - fp16_frb(c, a, 1); - break; - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp16_free(b); - } -} - void fp16_exp_cyc(fp16_t c, const fp16_t a, const bn_t b) { size_t l, w = RLC_WIDTH; fp16_t r, s, t[1 << (RLC_WIDTH - 2)]; @@ -1137,81 +1121,6 @@ void fp16_exp_cyc(fp16_t c, const fp16_t a, const bn_t b) { } } -void fp16_exp_cyc_gls(fp16_t c, const fp16_t a, const bn_t b) { - size_t i, l, _l[8]; - int8_t naf[8][RLC_FP_BITS + 1]; - fp16_t t[8]; - bn_t _b[8], n, x; - - if (bn_is_zero(b)) { - return fp16_set_dig(c, 1); - } - - bn_null(n); - bn_null(x); - - RLC_TRY { - bn_new(n); - bn_new(x); - for (i = 0; i < 8; i++) { - bn_null(_b[i]); - bn_new(_b[i]); - fp16_null(t[i]); - fp16_new(t[i]); - } - - ep_curve_get_ord(n); - fp_prime_get_par(x); - bn_abs(_b[0], b); - bn_mod(_b[0], _b[0], n); - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[0], _b[0]); - } - bn_rec_frb(_b, 8, _b[0], x, n, ep_curve_is_pairf() == EP_BN); - - fp16_copy(t[0], a); - for (int i = 1; i < 8; i++) { - fp16_gls(t[i], t[i - 1]); - } - - l = 0; - for (size_t i = 0; i < 8; i++) { - if (bn_sign(_b[i]) == RLC_NEG) { - fp16_inv_cyc(t[i], t[i]); - } - _l[i] = RLC_FP_BITS + 1; - bn_rec_naf(naf[i], &_l[i], _b[i], 2); - l = RLC_MAX(l, _l[i]); - } - - fp16_set_dig(c, 1); - for (int i = l - 1; i >= 0; i--) { - fp16_sqr_cyc(c, c); - for (size_t j = 0; j < 8; j++) { - if (naf[j][i] > 0) { - fp16_mul(c, c, t[j]); - } - if (naf[j][i] < 0) { - fp16_inv_cyc(t[j], t[j]); - fp16_mul(c, c, t[j]); - fp16_inv_cyc(t[j], t[j]); - } - } - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(n); - bn_free(x); - for (size_t i = 0; i < 8; i++) { - bn_free(_b[i]); - fp16_free(t[i]); - } - } -} - void fp16_exp_cyc_sim(fp16_t e, const fp16_t a, const bn_t b, const fp16_t c, const bn_t d) { int n0, n1; @@ -1389,15 +1298,11 @@ void fp18_back_cyc(fp18_t c, const fp18_t a) { int f = fp3_is_zero(a[1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp3_copy(t2, a[0][1]); - dv_copy_cond(t2[0], a[1][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[1], a[1][2][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[2], a[1][2][2], RLC_FP_DIGS, f); + fp3_copy_sec(t2, a[1][2], f); /* t0 = g4^2. */ fp3_mul(t0, a[0][1], t2); fp3_dbl(t2, t0); - dv_copy_cond(t0[0], t2[0], RLC_FP_DIGS, f); - dv_copy_cond(t0[1], t2[1], RLC_FP_DIGS, f); - dv_copy_cond(t0[2], t2[2], RLC_FP_DIGS, f); + fp3_copy_sec(t0, t2, f); /* t1 = 3 * g4^2 - 2 * g3. */ fp3_sub(t1, t0, a[0][2]); fp3_dbl(t1, t1); @@ -1409,15 +1314,11 @@ void fp18_back_cyc(fp18_t c, const fp18_t a) { /* t1 = (4 * g2). */ fp3_dbl(t1, a[1][0]); fp3_dbl(t1, t1); - dv_copy_cond(t1[0], a[0][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1], a[0][2][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[2], a[0][2][2], RLC_FP_DIGS, f); + fp3_copy_sec(t1, a[0][2], f); /* If unity, decompress to unity as well. */ f = fp18_cmp_dig(a, 1) == RLC_EQ; fp3_set_dig(t2, 1); - dv_copy_cond(t1[0], t2[0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1], t2[1], RLC_FP_DIGS, f); - dv_copy_cond(t1[2], t2[2], RLC_FP_DIGS, f); + fp3_copy_sec(t1, t2, f); /* t1 = 1/g3 or 1/(4 * g2), depending on the above. */ fp3_inv(t1, t1); @@ -1479,15 +1380,11 @@ void fp18_back_cyc_sim(fp18_t c[], const fp18_t a[], int n) { int f = fp3_is_zero(a[i][1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp3_copy(t2[i], a[i][0][1]); - dv_copy_cond(t2[i][0], a[i][1][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1], a[i][1][2][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][2], a[i][1][2][2], RLC_FP_DIGS, f); + fp3_copy_sec(t2[i], a[i][1][2], f); /* t0 = g4^2. */ fp3_mul(t0[i], a[i][0][1], t2[i]); fp3_dbl(t2[i], t0[i]); - dv_copy_cond(t0[i][0], t2[i][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1], t2[i][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][2], t2[i][2], RLC_FP_DIGS, f); + fp3_copy_sec(t0[i], t2[i], f); /* t1 = 3 * g4^2 - 2 * g3. */ fp3_sub(t1[i], t0[i], a[i][0][2]); fp3_dbl(t1[i], t1[i]); @@ -1499,15 +1396,11 @@ void fp18_back_cyc_sim(fp18_t c[], const fp18_t a[], int n) { /* t1 = (4 * g2). */ fp3_dbl(t1[i], a[i][1][0]); fp3_dbl(t1[i], t1[i]); - dv_copy_cond(t1[i][0], a[i][0][2][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1], a[i][0][2][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][2], a[i][0][2][2], RLC_FP_DIGS, f); + fp3_copy_sec(t1[i], a[i][0][2], f); /* If unity, decompress to unity as well. */ f = (fp18_cmp_dig(a[i], 1) == RLC_EQ); fp3_set_dig(t2[i], 1); - dv_copy_cond(t1[i][0], t2[i][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1], t2[i][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][2], t2[i][2], RLC_FP_DIGS, f); + fp3_copy_sec(t1[i], t2[i], f); } /* t1 = 1 / t1. */ @@ -1548,50 +1441,6 @@ void fp18_back_cyc_sim(fp18_t c[], const fp18_t a[], int n) { } } -static void fp18_gls(fp18_t c, const fp18_t a) { - fp18_t b; - - fp18_null(b); - - RLC_TRY { - fp18_new(b); - - 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 { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - fp18_free(b); - } -} - void fp18_exp_cyc(fp18_t c, const fp18_t a, const bn_t b) { size_t l, w = bn_ham(b); @@ -1723,89 +1572,6 @@ void fp18_exp_cyc(fp18_t c, const fp18_t a, const bn_t b) { } } -void fp18_exp_cyc_gls(fp18_t c, const fp18_t a, const bn_t b) { - size_t l, _l[6]; - int8_t naf[6][RLC_FP_BITS + 1]; - fp18_t t[6]; - bn_t _b[6], n, x; - - if (bn_is_zero(b)) { - return fp18_set_dig(c, 1); - } - - bn_null(n); - bn_null(x); - - RLC_TRY { - bn_new(n); - bn_new(x); - for (size_t i = 0; i < 6; i++) { - bn_null(_b[i]); - bn_new(_b[i]); - fp18_null(t[i]); - fp18_new(t[i]); - } - - fp_prime_get_par(x); - if (ep_curve_is_pairf() == EP_SG18) { - /* Compute base -3*u for the recoding below. */ - bn_dbl(n, x); - bn_add(x, x, n); - bn_neg(x, x); - } - ep_curve_get_ord(n); - bn_abs(_b[0], b); - bn_mod(_b[0], _b[0], n); - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[0], _b[0]); - } - bn_rec_frb(_b, 6, _b[0], x, n, ep_curve_is_pairf() == EP_BN); - - l = 0; - fp18_copy(t[0], a); - for (size_t i = 0; i < 6; i++) { - _l[i] = RLC_FP_BITS + 1; - bn_rec_naf(naf[i], &_l[i], _b[i], 2); - l = RLC_MAX(l, _l[i]); - if (i > 0) { - fp18_gls(t[i], t[i - 1]); - } - } - - for (size_t i = 0; i < 6; i++) { - if (bn_sign(_b[i]) == RLC_NEG) { - fp18_inv_cyc(t[i], t[i]); - } - } - - fp18_set_dig(c, 1); - for (int i = l - 1; i >= 0; i--) { - fp18_sqr_cyc(c, c); - for (int j = 0; j < 6; j++) { - if (naf[j][i] > 0) { - fp18_mul(c, c, t[j]); - } - if (naf[j][i] < 0) { - fp18_inv_cyc(t[j], t[j]); - fp18_mul(c, c, t[j]); - fp18_inv_cyc(t[j], t[j]); - } - } - } - } - RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(n); - bn_free(x); - for (size_t i = 0; i < 6; i++) { - bn_free(_b[i]); - fp18_free(t[i]); - } - } -} - void fp18_exp_cyc_sim(fp18_t e, const fp18_t a, const bn_t b, const fp18_t c, const bn_t d) { int i, n0, n1; @@ -2063,17 +1829,11 @@ void fp24_back_cyc(fp24_t c, const fp24_t a) { int f = fp4_is_zero(a[1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp4_copy(t2, a[2][0]); - dv_copy_cond(t2[0][0], a[2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[0][1], a[2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][0], a[2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][1], a[2][1][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t2, a[2][1], f); /* t0 = g4^2. */ fp4_mul(t0, a[2][0], t2); fp4_dbl(t2, t0); - dv_copy_cond(t0[0][0], t2[0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[0][1], t2[0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][0], t2[1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][1], t2[1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t0, t2, f); /* t1 = 3 * g4^2 - 2 * g3. */ fp4_sub(t1, t0, a[1][1]); fp4_dbl(t1, t1); @@ -2085,17 +1845,11 @@ void fp24_back_cyc(fp24_t c, const fp24_t a) { /* t1 = (4 * g2). */ fp4_dbl(t1, a[1][0]); fp4_dbl(t1, t1); - dv_copy_cond(t1[0][0], a[1][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1], a[1][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0], a[1][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1], a[1][1][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t1, a[1][1], f); /* If unity, decompress to unity as well. */ f = fp24_cmp_dig(a, 1) == RLC_EQ; fp4_set_dig(t2, 1); - dv_copy_cond(t1[0][0], t2[0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1], t2[0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0], t2[1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1], t2[1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t1, t2, f); fp4_inv(t1, t1); /* c_1 = g1. */ @@ -2156,17 +1910,11 @@ void fp24_back_cyc_sim(fp24_t c[], const fp24_t a[], int n) { int f = fp4_is_zero(a[i][1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp4_copy(t2[i], a[i][2][0]); - dv_copy_cond(t2[i][0][0], a[i][2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][0][1], a[i][2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][0], a[i][2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][1], a[i][2][1][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t2[i], a[i][2][1], f); /* t0 = g4^2. */ fp4_mul(t0[i], a[i][2][0], t2[i]); fp4_dbl(t2[i], t0[i]); - dv_copy_cond(t0[i][0][0], t2[i][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][0][1], t2[i][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][0], t2[i][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][1], t2[i][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t0[i], t2[i], f); /* t1 = 3 * g4^2 - 2 * g3. */ fp4_sub(t1[i], t0[i], a[i][1][1]); fp4_dbl(t1[i], t1[i]); @@ -2178,17 +1926,11 @@ void fp24_back_cyc_sim(fp24_t c[], const fp24_t a[], int n) { /* t1 = (4 * g2). */ fp4_dbl(t1[i], a[i][1][0]); fp4_dbl(t1[i], t1[i]); - dv_copy_cond(t1[i][0][0], a[i][1][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1], a[i][1][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0], a[i][1][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1], a[i][1][1][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t1[i], a[i][1][1], f); /* If unity, decompress to unity as well. */ f = fp24_cmp_dig(a[i], 1) == RLC_EQ; fp4_set_dig(t2[i], 1); - dv_copy_cond(t1[i][0][0], t2[i][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1], t2[i][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0], t2[i][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1], t2[i][1][1], RLC_FP_DIGS, f); + fp4_copy_sec(t1[i], t2[i], f); } /* t1 = 1 / t1. */ @@ -2360,81 +2102,6 @@ void fp24_exp_cyc(fp24_t c, const fp24_t a, const bn_t b) { } } -void fp24_exp_cyc_gls(fp24_t c, const fp24_t a, const bn_t b) { - size_t l, _l[8]; - int8_t naf[8][RLC_FP_BITS + 1]; - fp24_t t[8]; - bn_t _b[8], n, x; - - if (bn_is_zero(b)) { - fp24_set_dig(c, 1); - return; - } - - bn_null(n); - bn_null(x); - - RLC_TRY { - bn_new(n); - bn_new(x); - for (int i = 0; i < 8; i++) { - bn_null(_b[i]); - bn_new(_b[i]); - fp24_null(t[i]); - fp24_new(t[i]); - } - - ep_curve_get_ord(n); - fp_prime_get_par(x); - bn_abs(_b[0], b); - bn_mod(_b[0], _b[0], n); - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[0], _b[0]); - } - bn_rec_frb(_b, 8, _b[0], x, n, ep_curve_is_pairf() == EP_BN); - - fp24_copy(t[0], a); - for (size_t i = 1; i < 8; i++) { - fp24_frb(t[i], t[i - 1], 1); - } - - l = 0; - for (size_t i = 0; i < 8; i++) { - if (bn_sign(_b[i]) == RLC_NEG) { - fp24_inv_cyc(t[i], t[i]); - } - _l[i] = RLC_FP_BITS + 1; - bn_rec_naf(naf[i], &_l[i], _b[i], 2); - l = RLC_MAX(l, _l[i]); - } - - fp24_set_dig(c, 1); - for (int i = l - 1; i >= 0; i--) { - fp24_sqr_cyc(c, c); - for (size_t j = 0; j < 8; j++) { - if (naf[j][i] > 0) { - fp24_mul(c, c, t[j]); - } - if (naf[j][i] < 0) { - fp24_inv_cyc(t[j], t[j]); - fp24_mul(c, c, t[j]); - fp24_inv_cyc(t[j], t[j]); - } - } - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(n); - bn_free(x); - for (size_t i = 0; i < 8; i++) { - bn_free(_b[i]); - fp24_free(t[i]); - } - } -} - void fp24_exp_cyc_sim(fp24_t e, const fp24_t a, const bn_t b, const fp24_t c, const bn_t d) { int n0, n1; @@ -2692,25 +2359,11 @@ void fp48_back_cyc(fp48_t c, const fp48_t a) { int f = fp8_is_zero(a[1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp8_copy(t2, a[0][1]); - dv_copy_cond(t2[0][0][0], a[1][2][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[0][0][1], a[1][2][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[0][1][0], a[1][2][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[0][1][1], a[1][2][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][0][0], a[1][2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][0][1], a[1][2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][1][0], a[1][2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[1][1][1], a[1][2][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t2, a[1][2], f); /* t0 = g4^2. */ fp8_mul(t0, a[0][1], t2); fp8_dbl(t2, t0); - dv_copy_cond(t0[0][0][0], t2[0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[0][0][1], t2[0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[0][1][0], t2[0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[0][1][1], t2[0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][0][0], t2[1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][0][1], t2[1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][1][0], t2[1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[1][1][1], t2[1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t0, t2, f); /* t1 = 3 * g4^2 - 2 * g3. */ fp8_sub(t1, t0, a[0][2]); fp8_dbl(t1, t1); @@ -2722,25 +2375,11 @@ void fp48_back_cyc(fp48_t c, const fp48_t a) { /* t1 = (4 * g2). */ fp8_dbl(t1, a[1][0]); fp8_dbl(t1, t1); - dv_copy_cond(t1[0][0][0], a[0][2][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][0][1], a[0][2][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1][0], a[0][2][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1][1], a[0][2][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0][0], a[0][2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0][1], a[0][2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1][0], a[0][2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1][1], a[0][2][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t1, a[0][2], f); /* If unity, decompress to unity as well. */ f = fp48_cmp_dig(a, 1) == RLC_EQ; fp8_set_dig(t2, 1); - dv_copy_cond(t1[0][0][0], t2[0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][0][1], t2[0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1][0], t2[0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[0][1][1], t2[0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0][0], t2[1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][0][1], t2[1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1][0], t2[1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[1][1][1], t2[1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t1, t2, f); /* t1 = 1/g3 or 1/(4 * g2), depending on the above. */ fp8_inv(t1, t1); @@ -2802,25 +2441,11 @@ void fp48_back_cyc_sim(fp48_t c[], const fp48_t a[], int n) { int f = fp8_is_zero(a[i][1][0]); /* If f, t0[i] = 2 * g4 * g5, t1[i] = g3. */ fp8_copy(t2[i], a[i][0][1]); - dv_copy_cond(t2[i][0][0][0], a[i][1][2][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][0][0][1], a[i][1][2][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][0][1][0], a[i][1][2][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][0][1][1], a[i][1][2][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][0][0], a[i][1][2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][0][1], a[i][1][2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][1][0], a[i][1][2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][1][1][1], a[i][1][2][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t2[i], a[i][1][2], f); /* t0[i] = g4^2. */ fp8_mul(t0[i], a[i][0][1], t2[i]); fp8_dbl(t2[i], t0[i]); - dv_copy_cond(t0[i][0][0][0], t2[i][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][0][0][1], t2[i][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][0][1][0], t2[i][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][0][1][1], t2[i][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][0][0], t2[i][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][0][1], t2[i][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][1][0], t2[i][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][1][1][1], t2[i][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t0[i], t2[i], f); /* t1[i] = 3 * g4^2 - 2 * g3. */ fp8_sub(t1[i], t0[i], a[i][0][2]); fp8_dbl(t1[i], t1[i]); @@ -2832,25 +2457,11 @@ void fp48_back_cyc_sim(fp48_t c[], const fp48_t a[], int n) { /* t1[i] = (4 * g2). */ fp8_dbl(t1[i], a[i][1][0]); fp8_dbl(t1[i], t1[i]); - dv_copy_cond(t1[i][0][0][0], a[i][0][2][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][0][1], a[i][0][2][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1][0], a[i][0][2][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1][1], a[i][0][2][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0][0], a[i][0][2][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0][1], a[i][0][2][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1][0], a[i][0][2][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1][1], a[i][0][2][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t1[i], a[i][0][2], f); /* If unity, decompress to unity as well. */ f = fp48_cmp_dig(a[i], 1) == RLC_EQ; fp8_set_dig(t2[i], 1); - dv_copy_cond(t1[i][0][0][0], t2[i][0][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][0][1], t2[i][0][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1][0], t2[i][0][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][0][1][1], t2[i][0][1][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0][0], t2[i][1][0][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][0][1], t2[i][1][0][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1][0], t2[i][1][1][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][1][1][1], t2[i][1][1][1], RLC_FP_DIGS, f); + fp8_copy_sec(t1[i], t2[i], f); } /* t1 = 1 / t1. */ @@ -3022,81 +2633,6 @@ void fp48_exp_cyc(fp48_t c, const fp48_t a, const bn_t b) { } } -void fp48_exp_cyc_gls(fp48_t c, const fp48_t a, const bn_t b) { - size_t l, _l[16]; - int8_t naf[16][RLC_FP_BITS + 1]; - fp48_t t[16]; - bn_t _b[16], n, x; - - if (bn_is_zero(b)) { - fp48_set_dig(c, 1); - return; - } - - bn_null(n); - bn_null(x); - - RLC_TRY { - bn_new(n); - bn_new(x); - for (int i = 0; i < 8; i++) { - bn_null(_b[i]); - bn_new(_b[i]); - fp48_null(t[i]); - fp48_new(t[i]); - } - - ep_curve_get_ord(n); - fp_prime_get_par(x); - bn_abs(_b[0], b); - bn_mod(_b[0], _b[0], n); - if (bn_sign(b) == RLC_NEG) { - bn_neg(_b[0], _b[0]); - } - bn_rec_frb(_b, 16, _b[0], x, n, ep_curve_is_pairf() == EP_BN); - - fp48_copy(t[0], a); - for (size_t i = 1; i < 16; i++) { - fp48_frb(t[i], t[i - 1], 1); - } - - l = 0; - for (size_t i = 0; i < 16; i++) { - if (bn_sign(_b[i]) == RLC_NEG) { - fp48_inv_cyc(t[i], t[i]); - } - _l[i] = RLC_FP_BITS + 1; - bn_rec_naf(naf[i], &_l[i], _b[i], 2); - l = RLC_MAX(l, _l[i]); - } - - fp48_set_dig(c, 1); - for (int i = l - 1; i >= 0; i--) { - fp48_sqr_cyc(c, c); - for (size_t j = 0; j < 16; j++) { - if (naf[j][i] > 0) { - fp48_mul(c, c, t[j]); - } - if (naf[j][i] < 0) { - fp48_inv_cyc(t[j], t[j]); - fp48_mul(c, c, t[j]); - fp48_inv_cyc(t[j], t[j]); - } - } - } - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT); - } - RLC_FINALLY { - bn_free(n); - bn_free(x); - for (size_t i = 0; i < 16; i++) { - bn_free(_b[i]); - fp48_free(t[i]); - } - } -} - void fp48_exp_cyc_sim(fp48_t e, const fp48_t a, const bn_t b, const fp48_t c, const bn_t d) { int n0, n1; @@ -3353,19 +2889,11 @@ void fp54_back_cyc(fp54_t c, const fp54_t a) { int f = fp9_is_zero(a[1][0]); /* If f, t0 = 2 * g4 * g5, t1 = g3. */ fp9_copy(t2, a[2][0]); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t2[j][0], a[2][1][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[j][1], a[2][1][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[j][2], a[2][1][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t2, a[2][1], f); /* t0 = g4^2. */ fp9_mul(t0, a[2][0], t2); fp9_dbl(t2, t0); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t0[j][0], t2[j][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[j][1], t2[j][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[j][2], t2[j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t0, t2, f); /* t1 = 3 * g4^2 - 2 * g3. */ fp9_sub(t1, t0, a[1][1]); fp9_dbl(t1, t1); @@ -3377,19 +2905,11 @@ void fp54_back_cyc(fp54_t c, const fp54_t a) { /* t1 = (4 * g2). */ fp9_dbl(t1, a[1][0]); fp9_dbl(t1, t1); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t1[j][0], a[1][1][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[j][1], a[1][1][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[j][2], a[1][1][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t1, a[1][1], f); /* If unity, decompress to unity as well. */ f = fp54_cmp_dig(a, 1) == RLC_EQ; fp9_set_dig(t2, 1); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t1[j][0], t2[j][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[j][1], t2[j][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[j][2], t2[j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t1, t2, f); /* t1 = 1/(4 * g2). */ fp9_dbl(t1, a[1][0]); @@ -3453,19 +2973,11 @@ void fp54_back_cyc_sim(fp54_t c[], const fp54_t a[], int n) { int f = fp9_is_zero(a[i][1][0]); /* If f, t0[i] = 2 * g4 * g5, t1[i] = g3. */ fp9_copy(t2[i], a[i][2][0]); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t2[i][j][0], a[i][2][1][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][j][1], a[i][2][1][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t2[i][j][2], a[i][2][1][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t2[i], a[i][2][1], f); /* t0[i] = g4^2. */ fp9_mul(t0[i], a[i][2][0], t2[i]); fp9_dbl(t2[i], t0[i]); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t0[i][j][0], t2[i][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][j][1], t2[i][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t0[i][j][2], t2[i][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t0[i], t2[i], f); /* t1[i] = 3 * g4^2 - 2 * g3. */ fp9_sub(t1[i], t0[i], a[i][1][1]); fp9_dbl(t1[i], t1[i]); @@ -3477,19 +2989,11 @@ void fp54_back_cyc_sim(fp54_t c[], const fp54_t a[], int n) { /* t1[i] = (4 * g2). */ fp9_dbl(t1[i], a[i][1][0]); fp9_dbl(t1[i], t1[i]); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t1[i][j][0], a[i][1][1][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][j][1], a[i][1][1][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][j][2], a[i][1][1][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t1[i], a[i][1][1], f); /* If unity, decompress to unity as well. */ f = fp54_cmp_dig(a[i], 1) == RLC_EQ; fp9_set_dig(t2[i], 1); - for (int j = 0; j < 3; j++) { - dv_copy_cond(t1[i][j][0], t2[i][j][0], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][j][1], t2[i][j][1], RLC_FP_DIGS, f); - dv_copy_cond(t1[i][j][2], t2[i][j][2], RLC_FP_DIGS, f); - } + fp9_copy_sec(t1[i], t2[i], f); } /* t1 = 1 / t1. */ diff --git a/src/fpx/relic_fpx_field.c b/src/fpx/relic_fpx_field.c index fad2a4536..62096c0d1 100644 --- a/src/fpx/relic_fpx_field.c +++ b/src/fpx/relic_fpx_field.c @@ -38,9 +38,11 @@ int fp2_field_get_qnr() { /* Override some of the results when cubic non-residue is also needed. */ -#if FP_PRIME == 158 || FP_PRIME == 256 +#if FP_PRIME == 1150 + return 32; +#elif FP_PRIME == 158 || FP_PRIME == 256 return 4; -#elif FP_PRIME == 446 +#elif FP_PRIME == 446 && !defined(FP_QNRES) return 16; #else return core_get()->qnr2; diff --git a/src/fpx/relic_fpx_srt.c b/src/fpx/relic_fpx_srt.c index 574e36825..3b4ec0f6e 100644 --- a/src/fpx/relic_fpx_srt.c +++ b/src/fpx/relic_fpx_srt.c @@ -126,7 +126,7 @@ int fp2_srt(fp2_t c, const fp2_t a) { /* t1 = (a_0 - sqrt(t0)) / 2 */ fp_sub(t1, a[0], t1); fp_hlv(t1, t1); - dv_copy_cond(t0, t1, RLC_FP_DIGS, !fp_is_sqr(t0)); + fp_copy_sec(t0, t1, !fp_is_sqr(t0)); /* Should always be a quadratic residue. */ fp_srt(t2, t0); @@ -244,22 +244,12 @@ int fp3_srt(fp3_t c, const fp3_t a) { fp_mul(t0[0], t3[0], root); fp_mul(t0[1], t3[1], root); fp_mul(t0[2], t3[2], root); - dv_copy_cond(t3[0], t0[0], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); - dv_copy_cond(t3[1], t0[1], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); - dv_copy_cond(t3[2], t0[2], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); + fp3_copy_sec(t3, t0, fp3_cmp_dig(t2, 1) != RLC_EQ); fp_sqr(root, root); fp_mul(t0[0], t1[0], root); fp_mul(t0[1], t1[1], root); fp_mul(t0[2], t1[2], root); - dv_copy_cond(t1[0], t0[0], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); - dv_copy_cond(t1[1], t0[1], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); - dv_copy_cond(t1[2], t0[2], RLC_FP_DIGS, - fp3_cmp_dig(t2, 1) != RLC_EQ); + fp3_copy_sec(t1, t0, fp3_cmp_dig(t2, 1) != RLC_EQ); fp3_copy(t2, t1); } break; @@ -311,9 +301,7 @@ int fp3_srt(fp3_t c, const fp3_t a) { fp3_sqr(t0, t3); r = (fp3_cmp(t0, a) == RLC_EQ ? 1 : 0); fp3_zero(c); - dv_copy_cond(c[0], t3[0], RLC_FP_DIGS, r); - dv_copy_cond(c[1], t3[1], RLC_FP_DIGS, r); - dv_copy_cond(c[2], t3[2], RLC_FP_DIGS, r); + fp3_copy_sec(c, t3, r); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); } RLC_FINALLY { @@ -412,8 +400,7 @@ int fp4_srt(fp4_t c, const fp4_t a) { fp2_sub(t1, a[0], t1); fp_hlv(t1[0], t1[0]); fp_hlv(t1[1], t1[1]); - dv_copy_cond(t0[0], t1[0], RLC_FP_DIGS, !c0); - dv_copy_cond(t0[1], t1[1], RLC_FP_DIGS, !c0); + fp2_copy_sec(t0, t1, !c0); /* Should always be a quadratic residue. */ fp2_srt(t2, t0); /* c_0 = sqrt(t0) */ @@ -523,10 +510,7 @@ int fp8_srt(fp8_t c, const fp8_t a) { fp_hlv(t1[0][1], t1[0][1]); fp_hlv(t1[1][0], t1[1][0]); fp_hlv(t1[1][1], t1[1][1]); - dv_copy_cond(t0[0][0], t1[0][0], RLC_FP_DIGS, !c0); - dv_copy_cond(t0[0][1], t1[0][1], RLC_FP_DIGS, !c0); - dv_copy_cond(t0[1][0], t1[1][0], RLC_FP_DIGS, !c0); - dv_copy_cond(t0[1][1], t1[1][1], RLC_FP_DIGS, !c0); + fp4_copy_sec(t0, t1, !c0); /* Should always be a quadratic residue. */ fp4_srt(t2, t0); /* c_0 = sqrt(t0) */ @@ -640,8 +624,7 @@ int fp16_srt(fp16_t c, const fp16_t a) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { fp_hlv(t1[i][j][k], t1[i][j][k]); - dv_copy_cond(t0[i][j][k], t1[i][j][k], RLC_FP_DIGS, - !c0); + fp_copy_sec(t0[i][j][k], t1[i][j][k], !c0); } } } diff --git a/src/fpx/relic_fpx_util.c b/src/fpx/relic_fpx_util.c index bbc946c41..925b2e937 100644 --- a/src/fpx/relic_fpx_util.c +++ b/src/fpx/relic_fpx_util.c @@ -41,6 +41,11 @@ void fp2_copy(fp2_t c, const fp2_t a) { fp_copy(c[1], a[1]); } +void fp2_copy_sec(fp2_t c, const fp2_t a, dig_t bit) { + fp_copy_sec(c[0], a[0], bit); + fp_copy_sec(c[1], a[1], bit); +} + void fp2_zero(fp2_t a) { fp_zero(a[0]); fp_zero(a[1]); @@ -134,6 +139,12 @@ void fp3_copy(fp3_t c, const fp3_t a) { fp_copy(c[2], a[2]); } +void fp3_copy_sec(fp3_t c, const fp3_t a, dig_t bit) { + fp_copy_sec(c[0], a[0], bit); + fp_copy_sec(c[1], a[1], bit); + fp_copy_sec(c[2], a[2], bit); +} + void fp3_zero(fp3_t a) { fp_zero(a[0]); fp_zero(a[1]); @@ -191,6 +202,11 @@ void fp4_copy(fp4_t c, const fp4_t a) { fp2_copy(c[1], a[1]); } +void fp4_copy_sec(fp4_t c, const fp4_t a, dig_t bit) { + fp2_copy_sec(c[0], a[0], bit); + fp2_copy_sec(c[1], a[1], bit); +} + void fp4_zero(fp4_t a) { fp2_zero(a[0]); fp2_zero(a[1]); @@ -243,6 +259,12 @@ void fp6_copy(fp6_t c, const fp6_t a) { fp2_copy(c[2], a[2]); } +void fp6_copy_sec(fp6_t c, const fp6_t a, dig_t bit) { + fp2_copy_sec(c[0], a[0], bit); + fp2_copy_sec(c[1], a[1], bit); + fp2_copy_sec(c[2], a[2], bit); +} + void fp6_zero(fp6_t a) { fp2_zero(a[0]); fp2_zero(a[1]); @@ -300,6 +322,11 @@ void fp8_copy(fp8_t c, const fp8_t a) { fp4_copy(c[1], a[1]); } +void fp8_copy_sec(fp8_t c, const fp8_t a, dig_t bit) { + fp4_copy_sec(c[0], a[0], bit); + fp4_copy_sec(c[1], a[1], bit); +} + void fp8_zero(fp8_t a) { fp4_zero(a[0]); fp4_zero(a[1]); @@ -340,7 +367,7 @@ void fp8_read_bin(fp8_t a, const uint8_t *bin, size_t len) { fp4_read_bin(a[1], bin + 4 * RLC_FP_BYTES, 4 * RLC_FP_BYTES); } -void fp8_write_bin(uint8_t *bin, size_t len, const fp8_t a) { +void fp8_write_bin(uint8_t *bin, size_t len, const fp8_t a, int pack) { if (len != 8 * RLC_FP_BYTES) { RLC_THROW(ERR_NO_BUFFER); return; @@ -360,6 +387,12 @@ void fp9_copy(fp9_t c, const fp9_t a) { fp3_copy(c[2], a[2]); } +void fp9_copy_sec(fp9_t c, const fp9_t a, dig_t bit) { + fp3_copy_sec(c[0], a[0], bit); + fp3_copy_sec(c[1], a[1], bit); + fp3_copy_sec(c[2], a[2], bit); +} + void fp9_zero(fp9_t a) { fp3_zero(a[0]); fp3_zero(a[1]); @@ -417,6 +450,11 @@ void fp12_copy(fp12_t c, const fp12_t a) { fp6_copy(c[1], a[1]); } +void fp12_copy_sec(fp12_t c, const fp12_t a, dig_t bit) { + fp6_copy_sec(c[0], a[0], bit); + fp6_copy_sec(c[1], a[1], bit); +} + void fp12_zero(fp12_t a) { fp6_zero(a[0]); fp6_zero(a[1]); @@ -509,6 +547,11 @@ void fp16_copy(fp16_t c, const fp16_t a) { fp8_copy(c[1], a[1]); } +void fp16_copy_sec(fp16_t c, const fp16_t a, dig_t bit) { + fp8_copy_sec(c[0], a[0], bit); + fp8_copy_sec(c[1], a[1], bit); +} + void fp16_zero(fp16_t a) { fp8_zero(a[0]); fp8_zero(a[1]); @@ -554,8 +597,8 @@ void fp16_write_bin(uint8_t *bin, size_t len, const fp16_t a, int pack) { RLC_THROW(ERR_NO_BUFFER); return; } - fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0]); - fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1]); + fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0], 0); + fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1], 0); } void fp16_set_dig(fp16_t a, const dig_t b) { @@ -568,6 +611,11 @@ void fp18_copy(fp18_t c, const fp18_t a) { fp9_copy(c[1], a[1]); } +void fp18_copy_sec(fp18_t c, const fp18_t a, dig_t bit) { + fp9_copy_sec(c[0], a[0], bit); + fp9_copy_sec(c[1], a[1], bit); +} + void fp18_zero(fp18_t a) { fp9_zero(a[0]); fp9_zero(a[1]); @@ -661,6 +709,12 @@ void fp24_copy(fp24_t c, const fp24_t a) { fp8_copy(c[2], a[2]); } +void fp24_copy_sec(fp24_t c, const fp24_t a, dig_t bit) { + fp8_copy_sec(c[0], a[0], bit); + fp8_copy_sec(c[1], a[1], bit); + fp8_copy_sec(c[2], a[2], bit); +} + void fp24_zero(fp24_t a) { fp8_zero(a[0]); fp8_zero(a[1]); @@ -737,9 +791,9 @@ void fp24_write_bin(uint8_t *bin, size_t len, const fp24_t a, int pack) { if (len != 24 * RLC_FP_BYTES) { RLC_THROW(ERR_NO_BUFFER); } - fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0]); - fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1]); - fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[2]); + fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0], 0); + fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1], 0); + fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[2], 0); } } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -759,6 +813,11 @@ void fp48_copy(fp48_t c, const fp48_t a) { fp24_copy(c[1], a[1]); } +void fp48_copy_sec(fp48_t c, const fp48_t a, dig_t bit) { + fp24_copy_sec(c[0], a[0], bit); + fp24_copy_sec(c[1], a[1], bit); +} + void fp48_zero(fp48_t a) { fp24_zero(a[0]); fp24_zero(a[1]); @@ -823,10 +882,10 @@ void fp48_write_bin(uint8_t *bin, size_t len, const fp48_t a, int pack) { RLC_THROW(ERR_NO_BUFFER); } fp48_pck(t, a); - fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0][1]); - fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[0][2]); - fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1][0]); - fp8_write_bin(bin + 24 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1][2]); + fp8_write_bin(bin, 8 * RLC_FP_BYTES, a[0][1], 0); + fp8_write_bin(bin + 8 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[0][2], 0); + fp8_write_bin(bin + 16 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1][0], 0); + fp8_write_bin(bin + 24 * RLC_FP_BYTES, 8 * RLC_FP_BYTES, a[1][2], 0); } else { if (len != 48 * RLC_FP_BYTES) { RLC_THROW(ERR_NO_BUFFER); @@ -852,6 +911,12 @@ void fp54_copy(fp54_t c, const fp54_t a) { fp18_copy(c[2], a[2]); } +void fp54_copy_sec(fp54_t c, const fp54_t a, dig_t bit) { + fp18_copy_sec(c[0], a[0], bit); + fp18_copy_sec(c[1], a[1], bit); + fp18_copy_sec(c[2], a[2], bit); +} + void fp54_zero(fp54_t a) { fp18_zero(a[0]); fp18_zero(a[1]); diff --git a/src/low/easy/relic_fpx_add_low.c b/src/low/easy/relic_fpx_add_low.c index b0869e642..8954883f1 100755 --- a/src/low/easy/relic_fpx_add_low.c +++ b/src/low/easy/relic_fpx_add_low.c @@ -104,17 +104,19 @@ void fp2_norm_low(fp2_t c, fp2_t a) { #else int qnr = fp2_field_get_qnr(); switch (fp_prime_get_mod8()) { - case 3: - /* If p = 3 mod 8, (1 + i) is a QNR/CNR. */ - fp_neg(t[0], a[1]); - fp_add(c[1], a[0], a[1]); - fp_add(c[0], t[0], a[0]); - break; case 1: case 5: /* If p = 1,5 mod 8, (i) is a QNR/CNR. */ fp2_mul_art(c, a); break; + case 3: + if (qnr == 1) { + fp_copy(t[0], a[1]); + fp_add(c[1], a[0], a[1]); + fp_sub(c[0], a[0], t[0]); + break; + } + /* Otherwise, fall back to next one. */ case 7: /* If p = 7 mod 8, we choose (2^k + i) as QNR/CNR. */ fp2_mul_art(t, a); @@ -153,13 +155,6 @@ void fp2_nord_low(dv2_t c, dv2_t a) { #else int qnr = fp2_field_get_qnr(); switch (fp_prime_get_mod8()) { - case 3: - /* If p = 3 mod 8, (1 + i) is a QNR, i^2 = -1. */ - /* (a_0 + a_1 * i) * (1 + i) = (a_0 - a_1) + (a_0 + a_1) * i. */ - dv_copy(t[0], a[1], 2 * RLC_FP_DIGS); - fp_addc_low(c[1], a[0], a[1]); - fp_subc_low(c[0], a[0], t[0]); - break; case 1: case 5: /* If p = 1,5 mod 8, (i) is a QNR. */ @@ -172,6 +167,16 @@ void fp2_nord_low(dv2_t c, dv2_t a) { } dv_copy(c[1], t[0], 2 * RLC_FP_DIGS); break; + case 3: + if (qnr == 1) { + /* If p = 3 mod 8, (1 + i) is a QNR, i^2 = -1. */ + /* (a_0 + a_1 * i) * (1 + i) = (a_0 - a_1) + (a_0 + a_1) * i. */ + dv_copy(t[0], a[1], 2 * RLC_FP_DIGS); + fp_addc_low(c[1], a[0], a[1]); + fp_subc_low(c[0], a[0], t[0]); + break; + } + /* Otherwise, fall back to next one. */ case 7: /* If p = 7 mod 8, (2^k + i) is a QNR/CNR. */ dv_copy(t[0], a[0], 2 * RLC_FP_DIGS); diff --git a/src/low/x64-asm-12l/macro.s b/src/low/x64-asm-12l/macro.s index b1715dc22..96f64e70c 100644 --- a/src/low/x64-asm-12l/macro.s +++ b/src/low/x64-asm-12l/macro.s @@ -61,35 +61,21 @@ #define U0 0xC18CA908C52344BB */ /* AFG16-766 */ -#define P0 0xD1C2DA3812080101 -#define P1 0x7C7B86E2E778F618 -#define P2 0xCBDEA14B5B88FF11 -#define P3 0xCC0258598794E74A -#define P4 0x2C3C97E23451D33D -#define P5 0xD865BA50F2687698 -#define P6 0x7FE816EA1FC66244 -#define P7 0x28B32989A8983A80 -#define P8 0xA388C01776314278 -#define P9 0x103F6BCC973EF5C3 -#define P10 0x0BB883B2C64AF7BD -#define P11 0X3FFFFFC200801C27 -#define U0 0x30B120EB030700FF +#define P0 0xF45D1E791E054605 +#define P1 0xFCBC4220020A6592 +#define P2 0x211730168CD3106C +#define P3 0xC81A3A94170A2E5A +#define P4 0x04A837318C7897B6 +#define P5 0xA2902CAC0A117EAD +#define P6 0x4C8C62B406D882C8 +#define P7 0xDC0F8D8300A6748A +#define P8 0x67D35D389C7BD43C +#define P9 0x89F38FC6E7249EF1 +#define P10 0xC2E122127943E41E +#define P11 0x3FFFB8002607F379 +#define U0 0xF282381A203F6933 #elif FP_PRIME == 765 -/* AFG16-765 */ -#define P0 0x0000000000000001 -#define P1 0x00000000384F0100 -#define P2 0x7D00000000000000 -#define P3 0xFFFEE92F0199280F -#define P4 0xF10B013FFFFFFFFF -#define P5 0x4AC04FAC4912BADA -#define P6 0x6AC50E5A1A6AEAE4 -#define P7 0xEE9C1E7F21BD9E92 -#define P8 0x249F514A2A836FBF -#define P9 0x8866F5670199231B -#define P10 0xB2847B1232833CC3 -#define P11 0x16FAB993B0C96754 -#define U0 0xFFFFFFFFFFFFFFFF -/* FM16-765 +/* FM16-765 */ #define P0 0x1000EFC080000001 #define P1 0x0000000038223FF0 #define P2 0x0000000000000000 @@ -103,7 +89,6 @@ #define P10 0xBC5664C6F237BCB4 #define P11 0x166A30BEAF4CE221 #define U0 0xD000EFC07FFFFFFF -*/ #endif #if defined(__APPLE__) diff --git a/src/pc/relic_pc_exp.c b/src/pc/relic_pc_exp.c index 61bd8ed89..05d854385 100644 --- a/src/pc/relic_pc_exp.c +++ b/src/pc/relic_pc_exp.c @@ -31,6 +31,361 @@ #include "relic_pc.h" #include "relic_core.h" +/*============================================================================*/ +/* Private definitions */ +/*============================================================================*/ + +/** + * Apply Frobenius endomorphism in different pairing-friendly curve families. + * + * @param[in] c - the result. + * @param[in] a - the extension field element to exponentiate. + */ +static void gt_psi(gt_t c, const gt_t a) { + gt_t b; + + gt_null(b); + + RLC_TRY { + gt_new(b); + + switch (ep_curve_is_pairf()) { + case EP_K16: + /* u = (2*p^5 - p) mod r */ + gt_frb(b, a, 1); + gt_frb(c, b, 4); + gt_sqr(c, c); + gt_inv(b, b); + gt_mul(c, c, b); + break; + case EP_N16: + /* u = -p^5 mod r */ + gt_frb(c, a, 5); + gt_inv(c, c); + break; + case EP_SG18: + /* -3*u = (2*p^2 - p^5) mod r */ + gt_frb(b, a, 5); + gt_inv(b, b); + gt_frb(c, a, 2); + gt_sqr(c, c); + gt_mul(c, c, b); + break; + case EP_K18: + /* For KSS18, we have that x = p^4 - 3*p = (p^3 - 3)p mod n. */ + gt_sqr(b, a); + gt_mul(b, b, a); + gt_frb(c, a, 3); + gt_inv(b, b); + gt_mul(c, c, b); + gt_frb(c, c, 1); + break; + case EP_FM18: + /* For FM18, we have that u = (p^4-p) mod r. */ + gt_frb(b, a, 3); + gt_inv(b, b); + gt_mul(c, a, b); + gt_frb(c, c, 1); + gt_inv(c, c); + break; + default: + gt_frb(c, a, 1); + break; + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + gt_free(b); + } +} + +/** + * Size of a precomputation table using the double-table comb method. + */ +#define RLC_GT_TABLE (1 << (RLC_WIDTH - 2)) + +/** + * Exponentiates an element from G_T in constant time. + * + * @param[out] c - the result. + * @param[in] a - the element to exponentiate. + * @param[in] b - the exponent. + * @param[in] f - the maximum Frobenius power. + */ +void gt_exp_imp(gt_t c, const gt_t a, const bn_t b, size_t f) { + int8_t c0, n0, *reg = RLC_ALLOCA(int8_t, f * (RLC_FP_BITS + 1)); + int8_t *e = RLC_ALLOCA(int8_t, f), *s = RLC_ALLOCA(int8_t, f); + gt_t q, w, *t = RLC_ALLOCA(gt_t, f * RLC_GT_TABLE); + bn_t n, u, *_b = RLC_ALLOCA(bn_t, f); + size_t l, len, *_l = RLC_ALLOCA(size_t, f); + + if (reg == NULL || e == NULL || t == NULL || _b == NULL || _l == NULL) { + RLC_THROW(ERR_NO_MEMORY); + return; + } + + if (bn_is_zero(b)) { + RLC_FREE(reg); + RLC_FREE(e); + RLC_FREE(s); + RLC_FREE(t); + RLC_FREE(_b); + RLC_FREE(_l); + return gt_set_unity(c); + } + + bn_null(n); + bn_null(u); + gt_null(q); + gt_null(w); + + RLC_TRY { + bn_new(n); + bn_new(u); + gt_new(q); + gt_new(w); + for (size_t i = 0; i < f; i++) { + bn_null(_b[i]); + bn_new(_b[i]); + for (size_t j = 0; j < RLC_GT_TABLE; j++) { + gt_null(t[i * RLC_GT_TABLE + j]); + gt_new(t[i * RLC_GT_TABLE + j]); + } + } + + fp_prime_get_par(u); + if (ep_curve_is_pairf() == EP_SG18) { + /* Compute base -3*u for the recoding below. */ + bn_dbl(n, u); + bn_add(u, u, n); + bn_neg(u, u); + } + gt_get_ord(n); + bn_abs(_b[0], b); + bn_mod(_b[0], _b[0], n); + if (bn_sign(b) == RLC_NEG) { + bn_neg(_b[0], _b[0]); + } + bn_rec_frb(_b, f, _b[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + len = bn_bits(u) + (ep_curve_is_pairf() == EP_BN); + gt_copy(t[0], a); + for (size_t i = 0; i < f; i++) { + s[i] = bn_sign(_b[i]); + bn_abs(_b[i], _b[i]); + e[i] = bn_is_even(_b[i]); + _b[i]->dp[0] |= e[i]; + + _l[i] = RLC_FP_BITS + 1; + bn_rec_reg(reg + i * (RLC_FP_BITS + 1), &_l[i], _b[i], len, RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + gt_psi(t[i * RLC_GT_TABLE], t[(i - 1) * RLC_GT_TABLE]); + } + } + + for (size_t i = 0; i < f; i++) { + gt_inv(q, t[i * RLC_GT_TABLE]); + gt_copy_sec(q, t[i * RLC_GT_TABLE], s[i] == RLC_POS); + if (RLC_WIDTH > 2) { + gt_sqr(t[i * RLC_GT_TABLE], q); + gt_mul(t[i * RLC_GT_TABLE + 1], t[i * RLC_GT_TABLE], q); + for (size_t j = 2; j < RLC_GT_TABLE; j++) { + gt_mul(t[i * RLC_GT_TABLE + j], t[i * RLC_GT_TABLE + j - 1], + t[i * (RLC_GT_TABLE)]); + } + } + gt_copy(t[i * RLC_GT_TABLE], q); + } + + gt_set_unity(c); + for (int j = l - 1; j >= 0; j--) { + for (size_t i = 0; i < RLC_WIDTH - 1; i++) { + gt_sqr(c, c); + } + + for (size_t i = 0; i < f; i++) { + n0 = reg[i * (RLC_FP_BITS + 1) + j]; + c0 = (n0 >> 7); + n0 = ((n0 ^ c0) - c0) >> 1; + + for (size_t m = 0; m < RLC_GT_TABLE; m++) { + gt_copy_sec(w, t[i * RLC_GT_TABLE + m], m == n0); + } + + gt_inv(q, w); + gt_copy_sec(q, w, c0 == 0); + gt_mul(c, c, q); + + } + } + + for (size_t i = 0; i < f; i++) { + /* Tables are built with points already negated, so no need here. */ + gt_inv(q, t[i * RLC_GT_TABLE]); + gt_mul(q, c, q); + gt_copy_sec(c, q, e[i]); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + gt_free(q); + gt_free(w); + for (size_t i = 0; i < f; i++) { + bn_free(_b[i]); + for (size_t j = 0; j < RLC_GT_TABLE; j++) { + gt_free(t[i * RLC_GT_TABLE + j]); + } + } + RLC_FREE(reg); + RLC_FREE(e); + RLC_FREE(s); + RLC_FREE(t); + RLC_FREE(_b); + RLC_FREE(_l); + } +} + +/** + * Size of a precomputation table using the double-table comb method. + */ +#define RLC_GT_TABLE (1 << (RLC_WIDTH - 2)) + +/** + * Exponentiates an element from G_T in constant time. + * + * @param[out] c - the result. + * @param[in] a - the element to exponentiate. + * @param[in] b - the exponent. + * @param[in] f - the maximum Frobenius power. + */ +void gt_exp_gls_imp(gt_t c, const gt_t a, const bn_t b, size_t f) { + int8_t *naf = RLC_ALLOCA(int8_t, f * (RLC_FP_BITS + 1)); + int8_t n0, *s = RLC_ALLOCA(int8_t, f); + gt_t q, *t = RLC_ALLOCA(gt_t, f * RLC_GT_TABLE); + bn_t n, u, *_b = RLC_ALLOCA(bn_t, f); + size_t l, *_l = RLC_ALLOCA(size_t, f); + + if (naf == NULL || t == NULL || _b == NULL || _l == NULL) { + RLC_THROW(ERR_NO_MEMORY); + return; + } + + if (bn_is_zero(b)) { + RLC_FREE(naf); + RLC_FREE(s); + RLC_FREE(t); + RLC_FREE(_b); + RLC_FREE(_l); + return gt_set_unity(c); + } + + bn_null(n); + bn_null(u); + gt_null(q); + + RLC_TRY { + bn_new(n); + bn_new(u); + gt_new(q); + for (size_t i = 0; i < f; i++) { + bn_null(_b[i]); + bn_new(_b[i]); + for (size_t j = 0; j < RLC_GT_TABLE; j++) { + gt_null(t[i * RLC_GT_TABLE + j]); + gt_new(t[i * RLC_GT_TABLE + j]); + } + } + + fp_prime_get_par(u); + if (ep_curve_is_pairf() == EP_SG18) { + /* Compute base -3*u for the recoding below. */ + bn_dbl(n, u); + bn_add(u, u, n); + bn_neg(u, u); + } + gt_get_ord(n); + bn_abs(_b[0], b); + bn_mod(_b[0], _b[0], n); + if (bn_sign(b) == RLC_NEG) { + bn_neg(_b[0], _b[0]); + } + bn_rec_frb(_b, f, _b[0], u, n, ep_curve_is_pairf() == EP_BN); + + l = 0; + gt_copy(t[0], a); + for (size_t i = 0; i < f; i++) { + s[i] = bn_sign(_b[i]); + bn_abs(_b[i], _b[i]); + + _l[i] = RLC_FP_BITS + 1; + bn_rec_naf(naf + i * (RLC_FP_BITS + 1), &_l[i], _b[i], RLC_WIDTH); + l = RLC_MAX(l, _l[i]); + /* Apply Frobenius before flipping sign to build table. */ + if (i > 0) { + gt_psi(t[i * RLC_GT_TABLE], t[(i - 1) * RLC_GT_TABLE]); + } + } + + for (size_t i = 0; i < f; i++) { + gt_inv(q, t[i * RLC_GT_TABLE]); + gt_copy_sec(q, t[i * RLC_GT_TABLE], s[i] == RLC_POS); + if (RLC_WIDTH > 2) { + gt_sqr(t[i * RLC_GT_TABLE], q); + gt_mul(t[i * RLC_GT_TABLE + 1], t[i * RLC_GT_TABLE], q); + for (size_t j = 2; j < RLC_GT_TABLE; j++) { + gt_mul(t[i * RLC_GT_TABLE + j], t[i * RLC_GT_TABLE + j - 1], + t[i * (RLC_GT_TABLE)]); + } + } + gt_copy(t[i * RLC_GT_TABLE], q); + } + + gt_set_unity(c); + for (int j = l - 1; j >= 0; j--) { + gt_sqr(c, c); + + for (size_t i = 0; i < f; i++) { + n0 = naf[i * (RLC_FP_BITS + 1) + j]; + if (n0 > 0) { + gt_mul(c, c, t[i * RLC_GT_TABLE + n0 / 2]); + } + if (n0 < 0) { + gt_inv(q, t[i * RLC_GT_TABLE - n0 / 2]); + gt_mul(c, c, q); + } + } + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(n); + bn_free(u); + gt_free(q); + for (size_t i = 0; i < f; i++) { + bn_free(_b[i]); + for (size_t j = 0; j < RLC_GT_TABLE; j++) { + gt_free(t[i * RLC_GT_TABLE + j]); + } + } + RLC_FREE(naf); + RLC_FREE(s); + RLC_FREE(t); + RLC_FREE(_b); + RLC_FREE(_l); + } +} + /*============================================================================*/ /* Public definitions */ /*============================================================================*/ @@ -148,15 +503,31 @@ void gt_exp(gt_t c, const gt_t a, const bn_t b) { return; } -#if FP_PRIME < 1536 - RLC_CAT(RLC_GT_LOWER, exp_cyc_gls)(c, a, b); -#elif FP_PRIME == 1536 +#if FP_PRIME == 1536 || FP_PRIME == 544 RLC_CAT(RLC_GT_LOWER, exp_cyc)(c, a, b); +#elif FP_PRIME < 1536 + gt_exp_gls_imp(c, a, b, ep_curve_frdim()); #else RLC_CAT(RLC_GT_LOWER, exp)(c, a, b); #endif } +void gt_exp_sec(gt_t c, const gt_t a, const bn_t b) { + if (bn_bits(b) <= RLC_DIG) { + gt_exp_dig(c, a, b->dp[0]); + if (bn_sign(b) == RLC_NEG) { + gt_inv(c, c); + } + return; + } + +#if FP_PRIME <= 1536 + gt_exp_imp(c, a, b, ep_curve_frdim()); +#else + RLC_CAT(RLC_GT_LOWER, exp_monty)(c, a, b); +#endif +} + void gt_exp_dig(gt_t c, const gt_t a, dig_t b) { gt_t s, t; bn_t _b; diff --git a/src/pc/relic_pc_util.c b/src/pc/relic_pc_util.c index c6072137a..cbee2cf96 100644 --- a/src/pc/relic_pc_util.c +++ b/src/pc/relic_pc_util.c @@ -58,6 +58,8 @@ void gt_rand(gt_t a) { pp_exp_k16(a, a); #elif FP_PRIME == 508 || FP_PRIME == 768 || FP_PRIME == 638 && !defined(FP_QNRES) pp_exp_k18(a, a); +#elif FP_PRIME == 544 + pp_exp_k8(a, a); #else pp_exp_k12(a, a); #endif @@ -264,15 +266,14 @@ int g1_is_valid(const g1_t a) { } int g2_is_valid(const g2_t a) { +#if FP_PRIME >= 1536 + return g1_is_valid(a); +#else g2_t s, t, u, v, w; bn_t n; dig_t rem; int r = 0; -#if FP_PRIME >= 1536 - return g1_is_valid(a); -#else - if (g2_is_infty(a)) { return 0; } diff --git a/src/pp/relic_pp_dbl_k16.c b/src/pp/relic_pp_dbl_k16.c index 61992eebb..26803c0dd 100644 --- a/src/pp/relic_pp_dbl_k16.c +++ b/src/pp/relic_pp_dbl_k16.c @@ -113,29 +113,7 @@ void pp_dbl_k16_projc_basic(fp16_t l, ep4_t r, const ep4_t q, const ep_t p) { fp4_sqr(t0, q->x); fp4_sqr(t1, q->y); fp4_sqr(t2, q->z); - switch (ep_curve_opt_a()) { - case RLC_ZERO: - fp4_zero(t3); - break; - case RLC_ONE: - fp4_copy(t3, t2); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_mul_dig(t3[0][0], t2[0][0], ep_curve_get_a()[0]); - fp_mul_dig(t3[0][1], t2[0][1], ep_curve_get_a()[0]); - fp_mul_dig(t3[1][0], t2[1][0], ep_curve_get_a()[0]); - fp_mul_dig(t3[1][1], t2[1][1], ep_curve_get_a()[0]); - break; -#endif - default: - fp_mul(t3[0][0], t2[0][0], ep_curve_get_a()); - fp_mul(t3[0][1], t2[0][1], ep_curve_get_a()); - fp_mul(t3[1][0], t2[1][0], ep_curve_get_a()); - fp_mul(t3[1][1], t2[1][1], ep_curve_get_a()); - break; - } - fp4_mul_art(t3, t3); + ep4_curve_mul_a(t3, t2); /* x3 = (A - D)^2, l11 = (A - D + x1)^2 - x3 - A. */ fp4_sub(t5, t0, t3); @@ -236,29 +214,7 @@ void pp_dbl_k16_projc_lazyr(fp16_t l, ep4_t r, const ep4_t q, const ep_t p) { fp4_sqr(t0, q->x); fp4_sqr(t1, q->y); fp4_sqr(t2, q->z); - switch (ep_curve_opt_a()) { - case RLC_ZERO: - fp4_zero(t3); - break; - case RLC_ONE: - fp4_copy(t3, t2); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_mul_dig(t3[0][0], t2[0][0], ep_curve_get_a()[0]); - fp_mul_dig(t3[0][1], t2[0][1], ep_curve_get_a()[0]); - fp_mul_dig(t3[1][0], t2[1][0], ep_curve_get_a()[0]); - fp_mul_dig(t3[1][1], t2[1][1], ep_curve_get_a()[0]); - break; -#endif - default: - fp_mul(t3[0][0], t2[0][0], ep_curve_get_a()); - fp_mul(t3[0][1], t2[0][1], ep_curve_get_a()); - fp_mul(t3[1][0], t2[1][0], ep_curve_get_a()); - fp_mul(t3[1][1], t2[1][1], ep_curve_get_a()); - break; - } - fp4_mul_art(t3, t3); + ep4_curve_mul_a(t3, t2); /* x3 = (A - D)^2, l11 = (A - D + x1)^2 - x3 - A. */ fp4_sub(t5, t0, t3); diff --git a/src/pp/relic_pp_dbl_k18.c b/src/pp/relic_pp_dbl_k18.c index 2837eed99..a7e477c5a 100644 --- a/src/pp/relic_pp_dbl_k18.c +++ b/src/pp/relic_pp_dbl_k18.c @@ -117,8 +117,7 @@ void pp_dbl_k18_projc_basic(fp18_t l, ep3_t r, const ep3_t q, const ep_t p) { /* D = 3bC, general b. */ fp3_dbl(t3, t2); fp3_add(t3, t3, t2); - ep3_curve_get_b(t4); - fp3_mul(t3, t3, t4); + fp3_mul(t3, t3, ep3_curve_get_b()); /* E = (x1 + y1)^2 - A - B. */ fp3_add(t4, q->x, q->y); fp3_sqr(t4, t4); @@ -227,8 +226,7 @@ void pp_dbl_k18_projc_lazyr(fp18_t l, ep3_t r, const ep3_t q, const ep_t p) { /* D = 3bC, for general b. */ fp3_dbl(t3, t2); fp3_add(t3, t3, t2); - ep3_curve_get_b(t4); - fp3_mul(t3, t3, t4); + fp3_mul(t3, t3, ep3_curve_get_b()); /* E = (x1 + y1)^2 - A - B. */ fp3_add(t4, q->x, q->y); fp3_sqr(t4, t4); diff --git a/src/pp/relic_pp_dbl_k24.c b/src/pp/relic_pp_dbl_k24.c index c85e56303..c1c33a79d 100644 --- a/src/pp/relic_pp_dbl_k24.c +++ b/src/pp/relic_pp_dbl_k24.c @@ -121,8 +121,7 @@ void pp_dbl_k24_projc(fp24_t l, ep4_t r, const ep4_t q, const ep_t p) { /* D = 3bC, general b. */ fp4_dbl(t3, t2); fp4_add(t3, t3, t2); - ep4_curve_get_b(t4); - fp4_mul(t3, t3, t4); + fp4_mul(t3, t3, ep4_curve_get_b()); /* E = (x1 + y1)^2 - A - B. */ fp4_add(t4, q->x, q->y); diff --git a/src/pp/relic_pp_dbl_k48.c b/src/pp/relic_pp_dbl_k48.c index a58c9155f..f80fd4f55 100644 --- a/src/pp/relic_pp_dbl_k48.c +++ b/src/pp/relic_pp_dbl_k48.c @@ -109,8 +109,7 @@ void pp_dbl_k48_projc(fp48_t l, ep8_t r, const ep8_t q, const ep_t p) { /* D = 3bC, general b. */ fp8_dbl(t3, t2); fp8_add(t3, t3, t2); - ep8_curve_get_b(t4); - fp8_mul(t3, t3, t4); + fp8_mul(t3, t3, ep8_curve_get_b()); /* E = (x1 + y1)^2 - A - B. */ fp8_add(t4, q->x, q->y); diff --git a/src/pp/relic_pp_dbl_k8.c b/src/pp/relic_pp_dbl_k8.c index 1153f3d04..72db1ce90 100644 --- a/src/pp/relic_pp_dbl_k8.c +++ b/src/pp/relic_pp_dbl_k8.c @@ -180,25 +180,7 @@ void pp_dbl_k8_projc_basic(fp8_t l, ep2_t r, const ep2_t q, const ep_t p) { fp2_sqr(t0, q->x); fp2_sqr(t1, q->y); fp2_sqr(t2, q->z); - switch (ep_curve_opt_a()) { - case RLC_ZERO: - fp2_zero(t3); - break; - case RLC_ONE: - fp2_copy(t3, t2); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_mul_dig(t3[0], t2[0], ep_curve_get_a()[0]); - fp_mul_dig(t3[1], t2[1], ep_curve_get_a()[0]); - break; -#endif - default: - fp_mul(t3[0], t2[0], ep_curve_get_a()); - fp_mul(t3[1], t2[1], ep_curve_get_a()); - break; - } - fp2_mul_art(t3, t3); + ep2_curve_mul_a(t3, t2); /* x3 = (A - D)^2, l11 = (A - D + x1)^2 - x3 - A. */ fp2_sub(t5, t0, t3); @@ -293,28 +275,7 @@ void pp_dbl_k8_projc_lazyr(fp8_t l, ep2_t r, const ep2_t q, const ep_t p) { fp2_sqr(t0, q->x); fp2_sqr(t1, q->y); fp2_sqr(t2, q->z); - switch (ep_curve_opt_a()) { - case RLC_ZERO: - fp2_zero(t3); - break; - case RLC_ONE: - fp2_copy(t3, t2); - break; - case RLC_TWO: - fp2_dbl(t3, t2); - break; -#if FP_RDC != MONTY - case RLC_TINY: - fp_mul_dig(t3[0], t2[0], ep_curve_get_a()[0]); - fp_mul_dig(t3[1], t2[1], ep_curve_get_a()[0]); - break; -#endif - default: - fp_mul(t3[0], t2[0], ep_curve_get_a()); - fp_mul(t3[1], t2[1], ep_curve_get_a()); - break; - } - fp2_mul_art(t3, t3); + ep2_curve_mul_a(t3, t2); /* x3 = (A - D)^2, l11 = (A - D + x1)^2 - x3 - A. */ fp2_sub(t5, t0, t3); diff --git a/src/pp/relic_pp_map_k12.c b/src/pp/relic_pp_map_k12.c index 2446a083f..f82af9438 100644 --- a/src/pp/relic_pp_map_k12.c +++ b/src/pp/relic_pp_map_k12.c @@ -195,9 +195,8 @@ static void pp_mil_lit_k12(fp12_t r, ep_t *t, ep_t *p, ep2_t *q, int m, bn_t a) * @param[out] t - the resulting point. * @param[in] q - the first point of the pairing, in G_2. * @param[in] p - the second point of the pairing, in G_1. - * @param[in] a - the loop parameter. */ -static void pp_fin_k12_oatep(fp12_t r, ep2_t t, ep2_t q, ep_t p) { +static void pp_fin_k12_oatep(fp12_t r, ep2_t t, const ep2_t q, const ep_t p) { ep2_t q1, q2; fp12_t tmp; diff --git a/src/pp/relic_pp_map_k16.c b/src/pp/relic_pp_map_k16.c index 837076802..6ab261f85 100644 --- a/src/pp/relic_pp_map_k16.c +++ b/src/pp/relic_pp_map_k16.c @@ -198,29 +198,37 @@ static void pp_mil_lit_k16(fp16_t r, ep_t *t, ep_t *p, ep4_t *q, int m, bn_t a) * @param[in] p - the second point of the pairing, in G_1. * @param[in] a - the loop parameter. */ -static void pp_fin_k16_oatep(fp16_t r, ep4_t t, ep4_t q, ep_t p) { +static void pp_fin_k16_oatep(fp16_t r, ep4_t t, const ep4_t q, const ep_t p) { ep4_t q1, q2; fp16_t tmp; + ep_t _p; fp16_null(tmp); ep4_null(q1); ep4_null(q2); + ep_null(_p); RLC_TRY { ep4_new(q1); ep4_new(q2); fp16_new(tmp); - fp16_zero(tmp); + ep_new(_p); -#if EP_ADD == PROJC || EP_ADD == JACOB - fp_neg(p->x, p->x); +#if EP_ADD == BASIC + ep_neg(_p, p); +#else + fp_neg(_p->x, p->x); + fp_copy(_p->y, p->y); #endif + + fp16_zero(tmp); ep4_frb(q1, q, 1); - pp_add_k16(tmp, t, q1, p); + pp_add_k16(tmp, t, q1, _p); fp16_frb(tmp, tmp, 3); fp16_mul_dxs(r, r, tmp); - pp_dbl_k16(tmp, q2, q, p); + fp16_zero(tmp); + pp_dbl_k16(tmp, q2, q, _p); fp16_mul_dxs(r, r, tmp); } RLC_CATCH_ANY { RLC_THROW(ERR_CAUGHT); @@ -228,6 +236,7 @@ static void pp_fin_k16_oatep(fp16_t r, ep4_t t, ep4_t q, ep_t p) { fp16_free(tmp); ep4_free(q1); ep4_free(q2); + ep_free(_p); } } diff --git a/src/pp/relic_pp_map_k18.c b/src/pp/relic_pp_map_k18.c index 99f733ed9..083775443 100644 --- a/src/pp/relic_pp_map_k18.c +++ b/src/pp/relic_pp_map_k18.c @@ -196,9 +196,10 @@ static void pp_mil_lit_k18(fp18_t r, ep_t *t, ep_t *p, ep3_t *q, int m, bn_t a) * @param[out] t - the resulting point. * @param[in] q - the first point of the pairing, in G_2. * @param[in] p - the second point of the pairing, in G_1. - * @param[in] a - the loop parameter. + * @param[in] f - the flag to correct for the curve family. */ -static void pp_fin_k18_oatep(fp18_t r, ep3_t t, ep3_t q, ep_t p, int f) { +static void pp_fin_k18_oatep(fp18_t r, ep3_t t, const ep3_t q, const ep_t p, + int f) { fp18_t u, v; ep3_t _q; ep_t _p; diff --git a/src/pp/relic_pp_map_k54.c b/src/pp/relic_pp_map_k54.c index 5860fa94a..17b2b0181 100644 --- a/src/pp/relic_pp_map_k54.c +++ b/src/pp/relic_pp_map_k54.c @@ -181,6 +181,7 @@ void pp_map_k54(fp54_t r, const ep_t p, const fp9_t qx, const fp9_t qy) { if (bn_sign(a) == RLC_NEG) { fp54_inv_cyc(r, r); } + fp18_print(r[0]); pp_exp_k54(r, r); break; } diff --git a/src/pp/relic_pp_map_k8.c b/src/pp/relic_pp_map_k8.c index 0d5e2ee8f..bf2b9682a 100644 --- a/src/pp/relic_pp_map_k8.c +++ b/src/pp/relic_pp_map_k8.c @@ -163,3 +163,61 @@ void pp_map_oatep_k8(fp8_t r, const ep_t p, const ep2_t q) { bn_free(a); } } + +void pp_map_sim_oatep_k8(fp8_t r, const ep_t *p, const ep2_t *q, int m) { + ep_t *_p = RLC_ALLOCA(ep_t, m); + ep2_t *t = RLC_ALLOCA(ep2_t, m), *_q = RLC_ALLOCA(ep2_t, m); + bn_t a; + int i, j; + + RLC_TRY { + bn_null(a); + bn_new(a); + if (_p == NULL || _q == NULL || t == NULL) { + RLC_THROW(ERR_NO_MEMORY); + } + for (i = 0; i < m; i++) { + ep_null(_p[i]); + ep2_null(_q[i]); + ep2_null(t[i]); + ep_new(_p[i]); + ep2_new(_q[i]); + ep2_new(t[i]); + } + + j = 0; + for (i = 0; i < m; i++) { + if (!ep_is_infty(p[i]) && !ep2_is_infty(q[i])) { + ep_norm(_p[j], p[i]); + ep2_norm(_q[j++], q[i]); + } + } + + fp_prime_get_par(a); + fp8_set_dig(r, 1); + + if (j > 0) { + /* r = f_{|a|,Q}(P). */ + pp_mil_k8(r, t, _q, _p, j, a); + if (bn_sign(a) == RLC_NEG) { + fp8_inv_cyc(r, r); + ep2_neg(t[i], t[i]); + } + pp_exp_k8(r, r); + } + } + RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } + RLC_FINALLY { + bn_free(a); + for (i = 0; i < m; i++) { + ep_free(_p[i]); + ep4_free(_q[i]); + ep4_free(t[i]); + } + RLC_FREE(_p); + RLC_FREE(_q); + RLC_FREE(t); + } +} diff --git a/src/relic_util.c b/src/relic_util.c index 161084893..c69fb5cca 100644 --- a/src/relic_util.c +++ b/src/relic_util.c @@ -138,7 +138,7 @@ size_t util_bits_dig(dig_t a) { return RLC_DIG - arch_lzcnt(a); } -int util_cmp_const(const void *a, const void *b, size_t size) { +int util_cmp_sec(const void *a, const void *b, size_t size) { const uint8_t *_a = (const uint8_t *)a; const uint8_t *_b = (const uint8_t *)b; uint8_t result = 0; diff --git a/src/tmpl/relic_ep_add_tmpl.h b/src/tmpl/relic_ep_add_tmpl.h new file mode 100644 index 000000000..c847eb554 --- /dev/null +++ b/src/tmpl/relic_ep_add_tmpl.h @@ -0,0 +1,704 @@ +/* + * 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); \ + F##_dbl(t2, p->z); \ + F##_add(t2, t2, p->z); \ + C##_curve_mul_b(t2, t2); \ + F##_add(r->z, t1, t2); \ + F##_sub(t1, t1, t2); \ + } \ + F##_dbl(r->x, t0); \ + F##_add(t0, t0, r->x); \ + F##_dbl(t5, r->y); \ + F##_add(r->y, r->y, t5); \ + C##_curve_mul_b(r->y, r->y); \ + 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); \ + C##_curve_mul_a(r->z, t4); \ + F##_dbl(r->y, C##_curve_get_b()); \ + F##_add(r->y, r->y, C##_curve_get_b()); \ + F##_add(r->z, r->z, r->y); \ + } 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); \ + 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(t2, t2, t5); \ + C##_curve_mul_b(t2, t2); \ + F##_add(r->z, t1, t2); \ + F##_sub(t1, t1, t2); \ + F##_dbl(t5, r->y); \ + F##_add(r->y, r->y, t5); \ + C##_curve_mul_b(r->y, r->y); \ + 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_ep_dbl_tmpl.h b/src/tmpl/relic_ep_dbl_tmpl.h new file mode 100644 index 000000000..12918e277 --- /dev/null +++ b/src/tmpl/relic_ep_dbl_tmpl.h @@ -0,0 +1,430 @@ +/* + * 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 doubling 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_DBL_BASIC_IMP(C, F) \ + static void C##_dbl_basic_imp(C##_t r, F##_t s, const C##_t p) { \ + 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 = 1/2 * y1. */ \ + F##_dbl(t0, p->y); \ + F##_inv(t0, t0); \ + \ + /* t1 = 3 * x1^2 + a. */ \ + F##_sqr(t1, p->x); \ + F##_copy(t2, t1); \ + F##_dbl(t1, t1); \ + F##_add(t1, t1, t2); \ + F##_add(t1, t1, C##_curve_get_a()); \ + \ + /* t1 = (3 * x1^2 + a)/(2 * y1). */ \ + F##_mul(t1, t1, t0); \ + \ + if (s != NULL) { \ + F##_copy(s, t1); \ + } \ + \ + /* t2 = t1^2. */ \ + F##_sqr(t2, t1); \ + \ + /* x3 = t1^2 - 2 * x1. */ \ + F##_dbl(t0, p->x); \ + F##_sub(t0, t2, t0); \ + \ + /* y3 = t1 * (x1 - x3) - y1. */ \ + F##_sub(t2, p->x, t0); \ + F##_mul(t1, t1, t2); \ + F##_sub(r->y, t1, p->y); \ + \ + F##_copy(r->x, t0); \ + F##_copy(r->z, p->z); \ + \ + r->coord = BASIC; \ + } RLC_CATCH_ANY { \ + RLC_THROW(ERR_CAUGHT); \ + } RLC_FINALLY { \ + F##_free(t0); \ + F##_free(t1); \ + F##_free(t2); \ + } \ + } \ + +/** + * Defines a template for point addition in affine coordinates. + * + * Formulas for point doubling 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_DBL_PROJC_IMP(C, F) \ + static void C##_dbl_projc_imp(C##_t r, const C##_t p) { \ + 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); \ + \ + if (C##_curve_opt_a() == RLC_ZERO) { \ + /* Cost of 6M + 2S + 1m_3b + 9a. */ \ + F##_sqr(t0, p->y); \ + F##_mul(t3, p->x, p->y); \ + \ + if (p->coord == BASIC) { \ + /* Save 1M + 1S + 1m_b3 if z1 = 1. */ \ + F##_copy(t1, p->y); \ + F##_dbl(t2, C##_curve_get_b()); \ + F##_add(t2, t2, C##_curve_get_b()); \ + } else { \ + F##_mul(t1, p->y, p->z); \ + F##_sqr(t2, p->z); \ + F##_dbl(t5, t2); \ + F##_add(t5, t5, t2); \ + C##_curve_mul_b(t2, t5); \ + } \ + F##_dbl(r->z, t0); \ + F##_dbl(r->z, r->z); \ + F##_dbl(r->z, r->z); \ + F##_mul(r->x, t2, r->z); \ + F##_add(r->y, t0, t2); \ + F##_mul(r->z, t1, r->z); \ + F##_dbl(t1, t2); \ + F##_add(t2, t1, t2); \ + F##_sub(t0, t0, t2); \ + F##_mul(r->y, t0, r->y); \ + F##_add(r->y, r->x, r->y); \ + F##_mul(r->x, t0, t3); \ + F##_dbl(r->x, r->x); \ + } else { \ + F##_sqr(t0, p->x); \ + F##_sqr(t1, p->y); \ + F##_mul(t3, p->x, p->y); \ + F##_dbl(t3, t3); \ + F##_mul(t4, p->y, p->z); \ + \ + if (C##_curve_opt_a() == RLC_MIN3) { \ + /* Cost of 8M + 3S + 2mb + 21a. */ \ + if (p->coord == BASIC) { \ + /* Save 1S + 1m_b + 2a if z1 = 1. */ \ + F##_set_dig(t2, 3); \ + F##_copy(r->y, C##_curve_get_b()); \ + } else { \ + F##_sqr(t2, p->z); \ + C##_curve_mul_b(r->y, t2); \ + F##_dbl(t5, t2); \ + F##_add(t2, t2, t5); \ + } \ + F##_mul(r->z, p->x, p->z); \ + F##_dbl(r->z, r->z); \ + F##_sub(r->y, r->y, r->z); \ + F##_dbl(r->x, r->y); \ + F##_add(r->y, r->x, r->y); \ + F##_sub(r->x, t1, r->y); \ + F##_add(r->y, t1, r->y); \ + F##_mul(r->y, r->x, r->y); \ + F##_mul(r->x, t3, r->x); \ + C##_curve_mul_b(r->z, r->z); \ + F##_sub(t3, r->z, t2); \ + F##_sub(t3, t3, t0); \ + F##_dbl(r->z, t3); \ + F##_add(t3, t3, r->z); \ + F##_dbl(r->z, t0); \ + F##_add(t0, t0, r->z); \ + F##_sub(t0, t0, t2); \ + } else { \ + /* Common cost of 8M + 3S + 3m_a + 2m_3b + 15a. */ \ + if (p->coord == BASIC) { \ + /* Save 1S + 1m_b + 1m_a if z1 = 1. */ \ + F##_dbl(r->y, C##_curve_get_b()); \ + F##_add(r->y, r->y, C##_curve_get_b()); \ + F##_copy(t2, C##_curve_get_a()); \ + } else { \ + F##_sqr(t2, p->z); \ + F##_dbl(t5, t2); \ + F##_add(t5, t5, t2); \ + C##_curve_mul_b(r->y, t5); \ + C##_curve_mul_a(t2, t2); \ + } \ + F##_mul(r->z, p->x, p->z); \ + F##_dbl(r->z, r->z); \ + C##_curve_mul_a(r->x, r->z); \ + F##_add(r->y, r->x, r->y); \ + F##_sub(r->x, t1, r->y); \ + F##_add(r->y, t1, r->y); \ + F##_mul(r->y, r->x, r->y); \ + F##_mul(r->x, t3, r->x); \ + F##_dbl(t5, r->z); \ + F##_add(t5, t5, r->z); \ + C##_curve_mul_b(r->z, t5); \ + F##_sub(t3, t0, t2); \ + C##_curve_mul_a(t3, t3); \ + F##_add(t3, t3, r->z); \ + F##_dbl(r->z, t0); \ + F##_add(t0, t0, r->z); \ + F##_add(t0, t0, t2); \ + } \ + /* Common part with renamed variables. */ \ + F##_mul(t0, t0, t3); \ + F##_add(r->y, r->y, t0); \ + F##_dbl(t2, t4); \ + F##_mul(t0, t2, t3); \ + F##_sub(r->x, r->x, t0); \ + F##_mul(r->z, t2, t1); \ + F##_dbl(r->z, r->z); \ + F##_dbl(r->z, r->z); \ + } \ + 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 Jacobian coordinates. + * + * Formulas from http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html + * + * @param[in] C - the curve. + * @param[in] F - the field prefix. + */ +#define TMPL_DBL_JACOB_IMP(C, F) \ + static void C##_dbl_jacob_imp(C##_t r, const C##_t p) { \ + F##_t t0, t1, t2, t3, t4, t5; \ + \ + 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); \ + \ + if (p->coord != BASIC && C##_curve_opt_a() == RLC_MIN3) { \ + /* dbl-2001-b formulas: 3M + 5S + 8add + 1*4 + 2*8 + 1*3 */ \ + \ + /* t0 = delta = z1^2. */ \ + F##_sqr(t0, p->z); \ + \ + /* t1 = gamma = y1^2. */ \ + F##_sqr(t1, p->y); \ + \ + /* t2 = beta = x1 * y1^2. */ \ + F##_mul(t2, p->x, t1); \ + \ + /* t3 = alpha = 3 * (x1 - z1^2) * (x1 + z1^2). */ \ + F##_sub(t3, p->x, t0); \ + F##_add(t4, p->x, t0); \ + F##_mul(t4, t3, t4); \ + F##_dbl(t3, t4); \ + F##_add(t3, t3, t4); \ + \ + /* x3 = alpha^2 - 8 * beta. */ \ + F##_dbl(t2, t2); \ + F##_dbl(t2, t2); \ + F##_dbl(t5, t2); \ + F##_sqr(r->x, t3); \ + F##_sub(r->x, r->x, t5); \ + \ + /* z3 = (y1 + z1)^2 - gamma - delta. */ \ + F##_add(r->z, p->y, p->z); \ + F##_sqr(r->z, r->z); \ + F##_sub(r->z, r->z, t1); \ + F##_sub(r->z, r->z, t0); \ + \ + /* y3 = alpha * (4 * beta - x3) - 8 * gamma^2. */ \ + F##_dbl(t1, t1); \ + F##_sqr(t1, t1); \ + F##_dbl(t1, t1); \ + F##_sub(r->y, t2, r->x); \ + F##_mul(r->y, r->y, t3); \ + F##_sub(r->y, r->y, t1); \ + } else if (C##_curve_opt_a() == RLC_ZERO) { \ + /* dbl-2009-l formulas: 2M + 5S + 6add + 1*8 + 3*2 + 1*3.*/ \ + \ + /* A = X1^2 */ \ + F##_sqr(t0, p->x); \ + \ + /* B = Y1^2 */ \ + F##_sqr(t1, p->y); \ + \ + /* C = B^2 */ \ + F##_sqr(t2, t1); \ + \ + /* D = 2*((X1+B)^2-A-C) */ \ + F##_add(t1, t1, p->x); \ + F##_sqr(t1, t1); \ + F##_sub(t1, t1, t0); \ + F##_sub(t1, t1, t2); \ + F##_dbl(t1, t1); \ + \ + /* E = 3*A */ \ + F##_dbl(t3, t0); \ + F##_add(t0, t3, t0); \ + \ + /* F = E^2 */ \ + F##_sqr(t3, t0); \ + \ + /* Z3 = 2*Y1*Z1 */ \ + F##_mul(r->z, p->y, p->z); \ + F##_dbl(r->z, r->z); \ + \ + /* X3 = F-2*D */ \ + F##_sub(r->x, t3, t1); \ + F##_sub(r->x, r->x, t1); \ + \ + /* Y3 = E*(D-X3)-8*C */ \ + F##_sub(r->y, t1, r->x); \ + F##_mul(r->y, r->y, t0); \ + F##_dbl(t2, t2); \ + F##_dbl(t2, t2); \ + F##_dbl(t2, t2); \ + F##_sub(r->y, r->y, t2); \ + } else { \ + /* dbl-2007-bl: 1M + 8S + 1*a + 10add + 1*8 + 2*2 + 1*3 */ \ + \ + /* t0 = x1^2, t1 = y1^2, t2 = y1^4. */ \ + F##_sqr(t0, p->x); \ + F##_sqr(t1, p->y); \ + F##_sqr(t2, t1); \ + \ + if (p->coord != BASIC) { \ + /* t3 = z1^2. */ \ + F##_sqr(t3, p->z); \ + \ + if (C##_curve_opt_a() == RLC_ZERO) { \ + /* z3 = 2 * y1 * z1. */ \ + F##_mul(r->z, p->y, p->z); \ + F##_dbl(r->z, r->z); \ + } else { \ + /* z3 = (y1 + z1)^2 - y1^2 - z1^2. */ \ + F##_add(r->z, p->y, p->z); \ + F##_sqr(r->z, r->z); \ + F##_sub(r->z, r->z, t1); \ + F##_sub(r->z, r->z, t3); \ + } \ + } else { \ + /* z3 = 2 * y1. */ \ + F##_dbl(r->z, p->y); \ + } \ + \ + /* t4 = S = 2*((x1 + y1^2)^2 - x1^2 - y1^4). */ \ + F##_add(t4, p->x, t1); \ + F##_sqr(t4, t4); \ + F##_sub(t4, t4, t0); \ + F##_sub(t4, t4, t2); \ + F##_dbl(t4, t4); \ + \ + /* t5 = M = 3 * x1^2 + a * z1^4. */ \ + F##_dbl(t5, t0); \ + F##_add(t5, t5, t0); \ + if (p->coord != BASIC) { \ + F##_sqr(t3, t3); \ + C##_curve_mul_a(t1, t3); \ + F##_add(t5, t5, t1); \ + } else { \ + F##_add(t5, t5, C##_curve_get_a()); \ + } \ + /* x3 = T = M^2 - 2 * S. */ \ + F##_sqr(r->x, t5); \ + F##_dbl(t1, t4); \ + F##_sub(r->x, r->x, t1); \ + \ + /* y3 = M * (S - T) - 8 * y1^4. */ \ + F##_dbl(t2, t2); \ + F##_dbl(t2, t2); \ + F##_dbl(t2, t2); \ + F##_sub(t4, t4, r->x); \ + F##_mul(t5, t5, t4); \ + F##_sub(r->y, t5, t2); \ + } \ + \ + 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); \ + } \ + } \ + diff --git a/src/tmpl/relic_tmpl_map.h b/src/tmpl/relic_ep_map_tmpl.h similarity index 88% rename from src/tmpl/relic_tmpl_map.h rename to src/tmpl/relic_ep_map_tmpl.h index 2caaef1f7..7e31f88c7 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) \ @@ -46,9 +46,9 @@ } \ } -/* TODO: remove the ugly hack due to lack of support for JACOB in ep2. */ /* conditionally normalize result of isogeny map when not using projective coords */ #if EP_ADD == JACOB + #define TMPL_MAP_ISOMAP_NORM(PFX) \ do { \ /* Y = Ny * Dx * Z^2. */ \ @@ -62,22 +62,11 @@ PFX##_mul(q->x, t0, t2); \ PFX##_mul(q->x, q->x, q->z); \ q->coord = JACOB; \ - } while (0) + } while (0) \ + #elif EP_ADD == PROJC + #define TMPL_MAP_ISOMAP_NORM(PFX) \ - if (#PFX[2] == '2') { \ - /* Y = Ny * Dx * Z^2. */ \ - PFX##_mul(q->y, p->y, t1); \ - PFX##_mul(q->y, q->y, t3); \ - /* Z = Dx * Dy, t1 = Z^2. */ \ - PFX##_mul(q->z, t2, t3); \ - PFX##_sqr(t1, q->z); \ - PFX##_mul(q->y, q->y, t1); \ - /* X = Nx * Dy * Z. */ \ - PFX##_mul(q->x, t0, t2); \ - PFX##_mul(q->x, q->x, q->z); \ - q->coord = PROJC; \ - } else { \ /* Z = Dx * Dy. */ \ PFX##_mul(q->z, t2, t3); \ /* X = Nx * Dy. */ \ @@ -86,8 +75,9 @@ PFX##_mul(q->y, p->y, t1); \ PFX##_mul(q->y, q->y, t3); \ q->coord = PROJC; \ - } + #else + #define TMPL_MAP_ISOMAP_NORM(PFX) \ do { \ /* when working with affine coordinates, clear denominator */ \ @@ -103,7 +93,8 @@ /* z coord == 1 */ \ PFX##_set_dig(q->z, 1); \ q->coord = BASIC; \ - } while (0) + } while (0) \ + #endif /** @@ -153,7 +144,7 @@ PFX##_free(t2); \ PFX##_free(t3); \ } \ - } + } \ /* Conditionally call isogeny mapping function depending on whether EP_CTMAP is defined */ #ifdef EP_CTMAP @@ -162,16 +153,19 @@ if (CUR##_curve_is_ctmap()) { \ CUR##_iso(PT, PT); \ } \ - } while (0) + } while (0) \ + #else + #define TMPL_MAP_CALL_ISOMAP(CUR, PT) /* No isogeny map call in this case. */ + #endif /** * Simplified SWU mapping from Section 4 of * "Fast and simple constant-time hashing to the BLS12-381 Elliptic Curve" */ -#define TMPL_MAP_SSWU(CUR, PFX, PTR_TY, COPY_COND) \ +#define TMPL_MAP_SSWU(CUR, PFX, PTR_TY) \ static void CUR##_map_sswu(CUR##_t p, const PFX##_t t) { \ PFX##_t t0, t1, t2, t3; \ ctx_t *ctx = core_get(); \ @@ -203,11 +197,11 @@ const int e1 = PFX##_is_zero(t2); \ PFX##_neg(t3, u); /* t3 = -u */ \ /* exception: -u instead of u^2t^4 + ut^2 */ \ - COPY_COND(t2, t3, e1); \ + PFX##_copy_sec(t2, t3, e1); \ /* t2 = -1/u or 1/(u^2 * t^4 + u*t^2) */ \ PFX##_inv(t2, t2); \ PFX##_add_dig(t3, t2, 1); /* t3 = 1 + t2 */ \ - COPY_COND(t2, t3, e1 == 0); /* only add 1 if t2 != -1/u */ \ + PFX##_copy_sec(t2, t3, e1 == 0); /* add 1 if t2 != -1/u */ \ } \ /* e1 goes out of scope */ \ /* compute x1, g(x1) */ \ @@ -225,8 +219,8 @@ { \ /* try x2, g(x2) */ \ const int e1 = PFX##_is_sqr(p->y); \ - COPY_COND(p->x, t2, e1 == 0); \ - COPY_COND(p->y, t3, e1 == 0); \ + PFX##_copy_sec(p->x, t2, e1 == 0); \ + PFX##_copy_sec(p->y, t3, e1 == 0); \ } \ if (!PFX##_srt(p->y, p->y)) { \ RLC_THROW(ERR_NO_VALID); \ @@ -241,13 +235,13 @@ PFX##_free(t2); \ PFX##_free(t3); \ } \ - } + } \ /** * Shallue--van de Woestijne map, based on the definition from * draft-irtf-cfrg-hash-to-curve-06, Section 6.6.1 */ -#define TMPL_MAP_SVDW(CUR, PFX, PTR_TY, COPY_COND) \ +#define TMPL_MAP_SVDW(CUR, PFX, PTR_TY) \ static void CUR##_map_svdw(CUR##_t p, const PFX##_t t) { \ PFX##_t t1, t2, t3, t4; \ ctx_t *ctx = core_get(); \ @@ -280,10 +274,10 @@ { \ /* compute inv0(t3), i.e., 0 if t3 == 0, 1/t3 otherwise */ \ const int e0 = PFX##_is_zero(t3); \ - COPY_COND(t3, gU, e0); /* g(u) is nonzero */ \ + PFX##_copy_sec(t3, gU, e0); /* g(u) is nonzero */ \ PFX##_inv(t3, t3); \ PFX##_zero(t4); \ - COPY_COND(t3, t4, e0); \ + PFX##_copy_sec(t3, t4, e0); \ } \ /* e0 goes out of scope */ \ PFX##_mul(t4, t, t1); \ @@ -292,14 +286,14 @@ \ /* compute x1 and g(x1) */ \ PFX##_sub(p->x, mUover2, t4); \ - CUR##_rhs(p->y, p); \ + CUR##_rhs(p->y, p->x); \ { \ const int e0 = PFX##_is_sqr(p->y); \ /* compute x2 and g(x2) */ \ PFX##_add(t4, mUover2, t4); \ - COPY_COND(p->x, t4, e0 == 0); \ - CUR##_rhs(t1, p); \ - COPY_COND(p->y, t1, e0 == 0); \ + PFX##_copy_sec(p->x, t4, e0 == 0); \ + CUR##_rhs(t1, p->x); \ + PFX##_copy_sec(p->y, t1, e0 == 0); \ } \ { \ const int e1 = PFX##_is_sqr(p->y); \ @@ -309,9 +303,9 @@ PFX##_sqr(t1, t1); \ PFX##_mul(t1, t1, c4); \ PFX##_add(t1, t1, u); \ - COPY_COND(p->x, t1, e1 == 0); \ - CUR##_rhs(t2, p); \ - COPY_COND(p->y, t2, e1 == 0); \ + PFX##_copy_sec(p->x, t1, e1 == 0); \ + CUR##_rhs(t2, p->x); \ + PFX##_copy_sec(p->y, t2, e1 == 0); \ } \ if (!PFX##_srt(p->y, p->y)) { \ RLC_THROW(ERR_NO_VALID); \ @@ -326,4 +320,5 @@ PFX##_free(t3); \ PFX##_free(t4); \ } \ - } + } \ + diff --git a/test/test_dv.c b/test/test_dv.c index c272f33c5..29d4182e0 100644 --- a/test/test_dv.c +++ b/test/test_dv.c @@ -81,17 +81,17 @@ static int copy(void) { } } dv_copy(a, b, RLC_DV_DIGS); - TEST_ASSERT(dv_cmp_const(a, b, RLC_DV_DIGS) == RLC_EQ, end); + TEST_ASSERT(dv_cmp_sec(a, b, RLC_DV_DIGS) == RLC_EQ, end); } TEST_END; TEST_CASE("conditional copy and comparison are consistent") { rand_bytes((uint8_t *)a, RLC_DV_DIGS * sizeof(dig_t)); rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); - dv_copy_cond(a, b, RLC_DV_DIGS, 0); - TEST_ASSERT(dv_cmp_const(a, b, RLC_DV_DIGS) == RLC_NE, end); - dv_copy_cond(a, b, RLC_DV_DIGS, 1); - TEST_ASSERT(dv_cmp_const(a, b, RLC_DV_DIGS) == RLC_EQ, end); + dv_copy_sec(a, b, RLC_DV_DIGS, 0); + TEST_ASSERT(dv_cmp_sec(a, b, RLC_DV_DIGS) == RLC_NE, end); + dv_copy_sec(a, b, RLC_DV_DIGS, 1); + TEST_ASSERT(dv_cmp_sec(a, b, RLC_DV_DIGS) == RLC_EQ, end); } TEST_END; } RLC_CATCH_ANY { @@ -123,8 +123,8 @@ static int swap(void) { rand_bytes((uint8_t *)a, RLC_DV_DIGS * sizeof(dig_t)); rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); dv_copy(c, a, RLC_DV_DIGS); - dv_swap_cond(a, b, RLC_DV_DIGS, 1); - TEST_ASSERT(dv_cmp_const(c, b, RLC_DV_DIGS) == RLC_EQ, end); + dv_swap_sec(a, b, RLC_DV_DIGS, 1); + TEST_ASSERT(dv_cmp_sec(c, b, RLC_DV_DIGS) == RLC_EQ, end); } TEST_END; @@ -133,16 +133,16 @@ static int swap(void) { rand_bytes((uint8_t *)b, RLC_DV_DIGS * sizeof(dig_t)); dv_copy(c, a, RLC_DV_DIGS); dv_copy(d, b, RLC_DV_DIGS); - dv_swap_cond(a, b, RLC_DV_DIGS, 0); - TEST_ASSERT(dv_cmp_const(c, a, RLC_DV_DIGS) == RLC_EQ, end); - TEST_ASSERT(dv_cmp_const(d, b, RLC_DV_DIGS) == RLC_EQ, end); - TEST_ASSERT(dv_cmp_const(c, b, RLC_DV_DIGS) == RLC_NE, end); - TEST_ASSERT(dv_cmp_const(d, a, RLC_DV_DIGS) == RLC_NE, end); - dv_swap_cond(a, b, RLC_DV_DIGS, 1); - TEST_ASSERT(dv_cmp_const(c, b, RLC_DV_DIGS) == RLC_EQ, end); - TEST_ASSERT(dv_cmp_const(d, a, RLC_DV_DIGS) == RLC_EQ, end); - TEST_ASSERT(dv_cmp_const(c, a, RLC_DV_DIGS) == RLC_NE, end); - TEST_ASSERT(dv_cmp_const(d, b, RLC_DV_DIGS) == RLC_NE, end); + dv_swap_sec(a, b, RLC_DV_DIGS, 0); + TEST_ASSERT(dv_cmp_sec(c, a, RLC_DV_DIGS) == RLC_EQ, end); + TEST_ASSERT(dv_cmp_sec(d, b, RLC_DV_DIGS) == RLC_EQ, end); + TEST_ASSERT(dv_cmp_sec(c, b, RLC_DV_DIGS) == RLC_NE, end); + TEST_ASSERT(dv_cmp_sec(d, a, RLC_DV_DIGS) == RLC_NE, end); + dv_swap_sec(a, b, RLC_DV_DIGS, 1); + TEST_ASSERT(dv_cmp_sec(c, b, RLC_DV_DIGS) == RLC_EQ, end); + TEST_ASSERT(dv_cmp_sec(d, a, RLC_DV_DIGS) == RLC_EQ, end); + TEST_ASSERT(dv_cmp_sec(c, a, RLC_DV_DIGS) == RLC_NE, end); + TEST_ASSERT(dv_cmp_sec(d, b, RLC_DV_DIGS) == RLC_NE, end); } TEST_END; } RLC_CATCH_ANY { diff --git a/test/test_ep.c b/test/test_ep.c index 5c60e2560..5484a4ede 100644 --- a/test/test_ep.c +++ b/test/test_ep.c @@ -1394,15 +1394,17 @@ static int hashing(void) { #endif #if EP_MAP == SWIFT || !defined(STRIP) - if (ep_curve_opt_a() == RLC_ZERO || ep_curve_opt_b() == RLC_ZERO) { - TEST_CASE("swift point hashing is correct") { - rand_bytes(msg, sizeof(msg)); - ep_map_swift(a, msg, sizeof(msg)); - TEST_ASSERT(ep_on_curve(a) && ep_is_infty(a) == 0, end); - ep_mul(a, a, n); - TEST_ASSERT(ep_on_curve(a) && ep_is_infty(a) == 1, end); + if (!ep_curve_is_super()) { + if (ep_curve_opt_a() == RLC_ZERO || ep_curve_opt_b() == RLC_ZERO) { + TEST_CASE("swift point hashing is correct") { + rand_bytes(msg, sizeof(msg)); + ep_map_swift(a, msg, sizeof(msg)); + TEST_ASSERT(ep_on_curve(a) && ep_is_infty(a) == 0, end); + ep_mul(a, a, n); + TEST_ASSERT(ep_on_curve(a) && ep_is_infty(a) == 1, end); + } + TEST_END; } - TEST_END; } #endif } diff --git a/test/test_epx.c b/test/test_epx.c index d975bfdfc..5dda4c52f 100644 --- a/test/test_epx.c +++ b/test/test_epx.c @@ -219,9 +219,9 @@ static int addition2(void) { ep2_rand(a); ep2_set_infty(d); ep2_add(e, a, d); - TEST_ASSERT(ep2_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep2_cmp(a, e) == RLC_EQ, end); ep2_add(e, d, a); - TEST_ASSERT(ep2_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep2_cmp(a, e) == RLC_EQ, end); } TEST_END; TEST_CASE("point addition has inverse") { @@ -237,7 +237,7 @@ static int addition2(void) { ep2_rand(b); ep2_add(d, a, b); ep2_add_basic(e, a, b); - TEST_ASSERT(ep2_cmp(e, d) == RLC_EQ, end); + TEST_ASSERT(ep2_cmp(d, e) == RLC_EQ, end); } TEST_END; #endif @@ -281,6 +281,46 @@ static int addition2(void) { } TEST_END; #endif +#if EP_ADD == JACOB || !defined(STRIP) +#if !defined(EP_MIXED) || !defined(STRIP) + TEST_CASE("point addition in jacobian coordinates is correct") { + ep2_rand(a); + ep2_rand(b); + ep2_rand(c); + ep2_add_jacob(a, a, b); + ep2_add_jacob(b, b, c); + /* a and b in projective coordinates. */ + ep2_add_jacob(d, a, b); + ep2_norm(a, a); + ep2_norm(b, b); + ep2_add(e, a, b); + TEST_ASSERT(ep2_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("point addition in mixed coordinates (z2 = 1) is correct") { + ep2_rand(a); + ep2_rand(b); + /* a in projective, b in affine coordinates. */ + ep2_add_jacob(a, a, b); + ep2_add_jacob(d, a, b); + /* a in affine coordinates. */ + ep2_norm(a, a); + ep2_add(e, a, b); + TEST_ASSERT(ep2_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition in mixed coordinates (z1,z2 = 1) is correct") { + ep2_rand(a); + ep2_rand(b); + ep2_norm(a, a); + ep2_norm(b, b); + /* a and b in affine coordinates. */ + ep2_add(d, a, b); + ep2_add_jacob(e, a, b); + TEST_ASSERT(ep2_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -395,6 +435,26 @@ static int doubling2(void) { TEST_ASSERT(ep2_cmp(b, c) == RLC_EQ, end); } TEST_END; #endif + +#if EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("point doubling in jacobian coordinates is correct") { + ep2_rand(a); + /* a in projective coordinates. */ + ep2_dbl_jacob(a, a); + ep2_dbl_jacob(b, a); + ep2_norm(a, a); + ep2_dbl(c, a); + TEST_ASSERT(ep2_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point doubling in mixed coordinates (z1 = 1) is correct") { + ep2_rand(a); + ep2_dbl_jacob(b, a); + ep2_norm(b, b); + ep2_dbl(c, a); + TEST_ASSERT(ep2_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -567,6 +627,34 @@ static int multiplication2(void) { TEST_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + TEST_CASE("left-to-right regular point multiplication is correct") { + bn_zero(k); + ep2_mul_lwreg(r, p, k); + TEST_ASSERT(ep2_is_infty(r), end); + bn_set_dig(k, 1); + ep2_mul_lwreg(r, p, k); + TEST_ASSERT(ep2_cmp(p, r) == RLC_EQ, end); + ep2_rand(p); + ep2_mul_lwreg(r, p, n); + TEST_ASSERT(ep2_is_infty(r), end); + bn_rand_mod(k, n); + ep2_mul(q, p, k); + ep2_mul_lwreg(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep2_mul_lwreg(r, p, k); + ep2_neg(r, r); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep2_mul_lwreg(q, p, k); + bn_add(k, k, n); + ep2_mul_lwreg(r, p, k); + TEST_ASSERT(ep2_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + TEST_CASE("point multiplication by digit is correct") { ep2_mul_dig(r, p, 0); TEST_ASSERT(ep2_is_infty(r), end); @@ -1390,9 +1478,9 @@ static int addition3(void) { ep3_rand(a); ep3_set_infty(d); ep3_add(e, a, d); - TEST_ASSERT(ep3_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep3_cmp(a, e) == RLC_EQ, end); ep3_add(e, d, a); - TEST_ASSERT(ep3_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep3_cmp(a, e) == RLC_EQ, end); } TEST_END; TEST_CASE("point addition has inverse") { @@ -1408,7 +1496,7 @@ static int addition3(void) { ep3_rand(b); ep3_add(d, a, b); ep3_add_basic(e, a, b); - TEST_ASSERT(ep3_cmp(e, d) == RLC_EQ, end); + TEST_ASSERT(ep3_cmp(d, e) == RLC_EQ, end); } TEST_END; #endif @@ -1452,6 +1540,46 @@ static int addition3(void) { } TEST_END; #endif +#if EP_ADD == JACOB || !defined(STRIP) +#if !defined(EP_MIXED) || !defined(STRIP) + TEST_CASE("point addition in jacobian coordinates is correct") { + ep3_rand(a); + ep3_rand(b); + ep3_rand(c); + ep3_add_jacob(a, a, b); + ep3_add_jacob(b, b, c); + /* a and b in projective coordinates. */ + ep3_add_jacob(d, a, b); + ep3_norm(a, a); + ep3_norm(b, b); + ep3_add(e, a, b); + TEST_ASSERT(ep3_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("point addition in mixed coordinates (z2 = 1) is correct") { + ep3_rand(a); + ep3_rand(b); + /* a in projective, b in affine coordinates. */ + ep3_add_jacob(a, a, b); + ep3_add_jacob(d, a, b); + /* a in affine coordinates. */ + ep3_norm(a, a); + ep3_add(e, a, b); + TEST_ASSERT(ep3_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition in mixed coordinates (z1,z2 = 1) is correct") { + ep3_rand(a); + ep3_rand(b); + ep3_norm(a, a); + ep3_norm(b, b); + /* a and b in affine coordinates. */ + ep3_add(d, a, b); + ep3_add_jacob(e, a, b); + TEST_ASSERT(ep3_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -1566,6 +1694,26 @@ static int doubling3(void) { TEST_ASSERT(ep3_cmp(b, c) == RLC_EQ, end); } TEST_END; #endif + +#if EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("point doubling in jacobian coordinates is correct") { + ep3_rand(a); + /* a in projective coordinates. */ + ep3_dbl_jacob(a, a); + ep3_dbl_jacob(b, a); + ep3_norm(a, a); + ep3_dbl(c, a); + TEST_ASSERT(ep3_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point doubling in mixed coordinates (z1 = 1) is correct") { + ep3_rand(a); + ep3_dbl_jacob(b, a); + ep3_norm(b, b); + ep3_dbl(c, a); + TEST_ASSERT(ep3_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -1718,6 +1866,34 @@ static int multiplication3(void) { TEST_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + TEST_CASE("left-to-right regular point multiplication is correct") { + bn_zero(k); + ep3_mul_lwreg(r, p, k); + TEST_ASSERT(ep3_is_infty(r), end); + bn_set_dig(k, 1); + ep3_mul_lwreg(r, p, k); + TEST_ASSERT(ep3_cmp(p, r) == RLC_EQ, end); + ep3_rand(p); + ep3_mul_lwreg(r, p, n); + TEST_ASSERT(ep3_is_infty(r), end); + bn_rand_mod(k, n); + ep3_mul(q, p, k); + ep3_mul_lwreg(r, p, k); + TEST_ASSERT(ep3_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep3_mul_lwreg(r, p, k); + ep3_neg(r, r); + TEST_ASSERT(ep3_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep3_mul_lwreg(q, p, k); + bn_add(k, k, n); + ep3_mul_lwreg(r, p, k); + TEST_ASSERT(ep3_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + TEST_CASE("multiplication by digit is correct") { ep3_mul_dig(r, p, 0); TEST_ASSERT(ep3_is_infty(r), end); @@ -2419,9 +2595,9 @@ static int addition4(void) { ep4_rand(a); ep4_set_infty(d); ep4_add(e, a, d); - TEST_ASSERT(ep4_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep4_cmp(a, e) == RLC_EQ, end); ep4_add(e, d, a); - TEST_ASSERT(ep4_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep4_cmp(a, e) == RLC_EQ, end); } TEST_END; TEST_CASE("point addition has inverse") { @@ -2437,7 +2613,7 @@ static int addition4(void) { ep4_rand(b); ep4_add(d, a, b); ep4_add_basic(e, a, b); - TEST_ASSERT(ep4_cmp(e, d) == RLC_EQ, end); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); } TEST_END; #endif @@ -2481,6 +2657,46 @@ static int addition4(void) { } TEST_END; #endif +#if EP_ADD == JACOB || !defined(STRIP) +#if !defined(EP_MIXED) || !defined(STRIP) + TEST_CASE("point addition in jacobian coordinates is correct") { + ep4_rand(a); + ep4_rand(b); + ep4_rand(c); + ep4_add_jacob(a, a, b); + ep4_add_jacob(b, b, c); + /* a and b in projective coordinates. */ + ep4_add_jacob(d, a, b); + ep4_norm(a, a); + ep4_norm(b, b); + ep4_add(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("point addition in mixed coordinates (z2 = 1) is correct") { + ep4_rand(a); + ep4_rand(b); + /* a in projective, b in affine coordinates. */ + ep4_add_jacob(a, a, b); + ep4_add_jacob(d, a, b); + /* a in affine coordinates. */ + ep4_norm(a, a); + ep4_add(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition in mixed coordinates (z1,z2 = 1) is correct") { + ep4_rand(a); + ep4_rand(b); + ep4_norm(a, a); + ep4_norm(b, b); + /* a and b in affine coordinates. */ + ep4_add(d, a, b); + ep4_add_jacob(e, a, b); + TEST_ASSERT(ep4_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -2595,6 +2811,26 @@ static int doubling4(void) { TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); } TEST_END; #endif + +#if EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("point doubling in jacobian coordinates is correct") { + ep4_rand(a); + /* a in projective coordinates. */ + ep4_dbl_jacob(a, a); + ep4_dbl_jacob(b, a); + ep4_norm(a, a); + ep4_dbl(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point doubling in mixed coordinates (z1 = 1) is correct") { + ep4_rand(a); + ep4_dbl_jacob(b, a); + ep4_norm(b, b); + ep4_dbl(c, a); + TEST_ASSERT(ep4_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -2747,6 +2983,34 @@ static int multiplication4(void) { TEST_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + TEST_CASE("left-to-right regular point multiplication is correct") { + bn_zero(k); + ep4_mul_lwreg(r, p, k); + TEST_ASSERT(ep4_is_infty(r), end); + bn_set_dig(k, 1); + ep4_mul_lwreg(r, p, k); + TEST_ASSERT(ep4_cmp(p, r) == RLC_EQ, end); + ep4_rand(p); + ep4_mul_lwreg(r, p, n); + TEST_ASSERT(ep4_is_infty(r), end); + bn_rand_mod(k, n); + ep4_mul(q, p, k); + ep4_mul_lwreg(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep4_mul_lwreg(r, p, k); + ep4_neg(r, r); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep4_mul_lwreg(q, p, k); + bn_add(k, k, n); + ep4_mul_lwreg(r, p, k); + TEST_ASSERT(ep4_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + TEST_CASE("multiplication by digit is correct") { ep4_mul_dig(r, p, 0); TEST_ASSERT(ep4_is_infty(r), end); @@ -3448,9 +3712,9 @@ static int addition8(void) { ep8_rand(a); ep8_set_infty(d); ep8_add(e, a, d); - TEST_ASSERT(ep8_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep8_cmp(a, e) == RLC_EQ, end); ep8_add(e, d, a); - TEST_ASSERT(ep8_cmp(e, a) == RLC_EQ, end); + TEST_ASSERT(ep8_cmp(a, e) == RLC_EQ, end); } TEST_END; TEST_CASE("point addition has inverse") { @@ -3466,7 +3730,7 @@ static int addition8(void) { ep8_rand(b); ep8_add(d, a, b); ep8_add_basic(e, a, b); - TEST_ASSERT(ep8_cmp(e, d) == RLC_EQ, end); + TEST_ASSERT(ep8_cmp(d, e) == RLC_EQ, end); } TEST_END; #endif @@ -3510,6 +3774,46 @@ static int addition8(void) { } TEST_END; #endif +#if EP_ADD == JACOB || !defined(STRIP) +#if !defined(EP_MIXED) || !defined(STRIP) + TEST_CASE("point addition in jacobian coordinates is correct") { + ep8_rand(a); + ep8_rand(b); + ep8_rand(c); + ep8_add_jacob(a, a, b); + ep8_add_jacob(b, b, c); + /* a and b in projective coordinates. */ + ep8_add_jacob(d, a, b); + ep8_norm(a, a); + ep8_norm(b, b); + ep8_add(e, a, b); + TEST_ASSERT(ep8_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif + + TEST_CASE("point addition in mixed coordinates (z2 = 1) is correct") { + ep8_rand(a); + ep8_rand(b); + /* a in projective, b in affine coordinates. */ + ep8_add_jacob(a, a, b); + ep8_add_jacob(d, a, b); + /* a in affine coordinates. */ + ep8_norm(a, a); + ep8_add(e, a, b); + TEST_ASSERT(ep8_cmp(d, e) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point addition in mixed coordinates (z1,z2 = 1) is correct") { + ep8_rand(a); + ep8_rand(b); + ep8_norm(a, a); + ep8_norm(b, b); + /* a and b in affine coordinates. */ + ep8_add(d, a, b); + ep8_add_jacob(e, a, b); + TEST_ASSERT(ep8_cmp(d, e) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -3624,6 +3928,26 @@ static int doubling8(void) { TEST_ASSERT(ep8_cmp(b, c) == RLC_EQ, end); } TEST_END; #endif + +#if EP_ADD == JACOB || !defined(STRIP) + TEST_CASE("point doubling in jacobian coordinates is correct") { + ep8_rand(a); + /* a in projective coordinates. */ + ep8_dbl_jacob(a, a); + ep8_dbl_jacob(b, a); + ep8_norm(a, a); + ep8_dbl(c, a); + TEST_ASSERT(ep8_cmp(b, c) == RLC_EQ, end); + } TEST_END; + + TEST_CASE("point doubling in mixed coordinates (z1 = 1) is correct") { + ep8_rand(a); + ep8_dbl_jacob(b, a); + ep8_norm(b, b); + ep8_dbl(c, a); + TEST_ASSERT(ep8_cmp(b, c) == RLC_EQ, end); + } TEST_END; +#endif } RLC_CATCH_ANY { RLC_ERROR(end); @@ -3776,6 +4100,34 @@ static int multiplication8(void) { TEST_END; #endif +#if EP_MUL == LWREG || !defined(STRIP) + TEST_CASE("left-to-right regular point multiplication is correct") { + bn_zero(k); + ep8_mul_lwreg(r, p, k); + TEST_ASSERT(ep8_is_infty(r), end); + bn_set_dig(k, 1); + ep8_mul_lwreg(r, p, k); + TEST_ASSERT(ep8_cmp(p, r) == RLC_EQ, end); + ep8_rand(p); + ep8_mul_lwreg(r, p, n); + TEST_ASSERT(ep8_is_infty(r), end); + bn_rand_mod(k, n); + ep8_mul(q, p, k); + ep8_mul_lwreg(r, p, k); + TEST_ASSERT(ep8_cmp(q, r) == RLC_EQ, end); + bn_neg(k, k); + ep8_mul_lwreg(r, p, k); + ep8_neg(r, r); + TEST_ASSERT(ep8_cmp(q, r) == RLC_EQ, end); + bn_rand_mod(k, n); + ep8_mul_lwreg(q, p, k); + bn_add(k, k, n); + ep8_mul_lwreg(r, p, k); + TEST_ASSERT(ep8_cmp(q, r) == RLC_EQ, end); + } + TEST_END; +#endif + TEST_CASE("multiplication by digit is correct") { ep8_mul_dig(r, p, 0); TEST_ASSERT(ep8_is_infty(r), end); diff --git a/test/test_fp.c b/test/test_fp.c index a25936fc5..49fa961a3 100644 --- a/test/test_fp.c +++ b/test/test_fp.c @@ -87,6 +87,14 @@ static int util(void) { fp_copy(b, a); TEST_ASSERT(fp_cmp(a, b) == RLC_EQ, end); } + fp_rand(a); + fp_rand(b); + if (fp_cmp(a, b) != RLC_EQ) { + fp_copy_sec(b, a, 0); + TEST_ASSERT(fp_cmp(a, b) != RLC_EQ, end); + fp_copy_sec(b, a, 1); + TEST_ASSERT(fp_cmp(a, b) == RLC_EQ, end); + } } TEST_END; @@ -1145,7 +1153,7 @@ static int cube_root(void) { fp_mul(c, c, a); TEST_ASSERT(fp_crt(b, c), end); if (fp_prime_get_cnr()) { - fp_copy(d, fp_prime_get_crt()); + fp_copy(d, (const dig_t *)fp_prime_get_crt()); while (fp_cmp_dig(d, 1) != RLC_EQ) { fp_copy(c, d); fp_sqr(d, d); diff --git a/test/test_fpx.c b/test/test_fpx.c index aa922c2c4..45da38fb6 100644 --- a/test/test_fpx.c +++ b/test/test_fpx.c @@ -476,10 +476,6 @@ static int multiplication2(void) { fp2_mul_art(c, a); break; case 3: - fp_set_dig(c[0], 1); - fp_set_dig(c[1], 1); - fp2_mul(c, a, c); - break; case 7: fp_set_dig(c[0], fp2_field_get_qnr()); fp_set_dig(c[1], 1); @@ -2953,7 +2949,7 @@ static int util8(void) { TEST_CASE("reading and writing a finite field element are consistent") { fp8_rand(a); - fp8_write_bin(bin, sizeof(bin), a); + fp8_write_bin(bin, sizeof(bin), a, 0); fp8_read_bin(b, bin, sizeof(bin)); TEST_ASSERT(fp8_cmp(a, b) == RLC_EQ, end); } @@ -4681,29 +4677,6 @@ static int cyclotomic12(void) { TEST_ASSERT(fp12_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 12) { - TEST_CASE("cyclotomic exponentiation in subgroup is correct") { - fp12_rand(a); - pp_exp_k12(a, a); - bn_zero(f); - fp12_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp12_cmp_dig(c, 1) == RLC_EQ, end); - bn_set_dig(f, 1); - fp12_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp12_cmp(c, a) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp12_exp(b, a, f); - fp12_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp12_cmp(b, c) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp12_exp_cyc_gls(b, a, f); - bn_neg(f, f); - fp12_exp_cyc_gls(c, a, f); - fp12_inv_cyc(c, c); - TEST_ASSERT(fp12_cmp(b, c) == RLC_EQ, end); - } TEST_END; - } - TEST_CASE("sparse cyclotomic exponentiation is correct") { int g[3] = {0, 0, RLC_FP_BITS - 1}; do { @@ -5411,7 +5384,7 @@ static int cyclotomic16(void) { TEST_ASSERT(fp16_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 16) { + if (ep_curve_is_pairf() && ep_curve_embed() == 16) { TEST_CASE("cyclotomic exponentiation in subgroup is correct") { fp16_rand(a); pp_exp_k16(a, a); @@ -6181,29 +6154,6 @@ static int cyclotomic18(void) { TEST_ASSERT(fp18_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 18) { - TEST_CASE("cyclotomic exponentiation in subgroup is correct") { - fp18_rand(a); - pp_exp_k18(a, a); - bn_zero(f); - fp18_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp18_cmp_dig(c, 1) == RLC_EQ, end); - bn_set_dig(f, 1); - fp18_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp18_cmp(c, a) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp18_exp(b, a, f); - fp18_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp18_cmp(b, c) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp18_exp_cyc_gls(b, a, f); - bn_neg(f, f); - fp18_exp_cyc_gls(c, a, f); - fp18_inv_cyc(c, c); - TEST_ASSERT(fp18_cmp(b, c) == RLC_EQ, end); - } TEST_END; - } - TEST_CASE("sparse cyclotomic exponentiation is correct") { int g[3] = {0, 0, RLC_FP_BITS - 1}; do { @@ -6957,29 +6907,6 @@ static int cyclotomic24(void) { TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 24) { - TEST_CASE("cyclotomic exponentiation in subgroup is correct") { - fp24_rand(a); - pp_exp_k24(a, a); - bn_zero(f); - fp24_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp24_cmp_dig(c, 1) == RLC_EQ, end); - bn_set_dig(f, 1); - fp24_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp24_cmp(c, a) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_DIG); - fp24_exp(b, a, f); - fp24_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp24_exp_cyc_gls(b, a, f); - bn_neg(f, f); - fp24_exp_cyc_gls(c, a, f); - fp24_inv_cyc(c, c); - TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); - } TEST_END; - } - TEST_CASE("sparse cyclotomic exponentiation is correct") { int g[3] = {0, 0, RLC_FP_BITS - 1}; do { @@ -7772,29 +7699,6 @@ static int cyclotomic48(void) { TEST_ASSERT(fp48_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 48) { - TEST_CASE("cyclotomic exponentiation in subgroup is correct") { - fp48_rand(a); - pp_exp_k48(a, a); - bn_zero(f); - fp48_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp48_cmp_dig(c, 1) == RLC_EQ, end); - bn_set_dig(f, 1); - fp48_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp48_cmp(c, a) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_DIG); - fp48_exp(b, a, f); - fp48_exp_cyc_gls(c, a, f); - TEST_ASSERT(fp48_cmp(b, c) == RLC_EQ, end); - bn_rand(f, RLC_POS, RLC_FP_BITS); - fp48_exp_cyc_gls(b, a, f); - bn_neg(f, f); - fp48_exp_cyc_gls(c, a, f); - fp48_inv_cyc(c, c); - TEST_ASSERT(fp48_cmp(b, c) == RLC_EQ, end); - } TEST_END; - } - TEST_CASE("sparse cyclotomic exponentiation is correct") { int g[3] = {0, 0, RLC_FP_BITS - 1}; do { @@ -8615,7 +8519,9 @@ static int inversion54(void) { fp54_conv_cyc(a, a); fp54_inv(b, a); fp54_inv_cyc(c, a); - TEST_ASSERT(fp54_cmp(b, c) == RLC_EQ, end); + fp18_print(b[0]); + fp18_print(c[0]); + TEST_ASSERT(fp18_cmp(b[0], c[0]) == RLC_EQ, end); } TEST_END; } RLC_CATCH_ANY { @@ -8783,7 +8689,7 @@ int main(void) { } /* Only execute these if there is an assigned cubic non-residue. */ - if (fp_prime_get_cnr()) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 3)) { util_print("\n-- Cubic extension: %d as CNR\n", fp_prime_get_cnr()); util_banner("Utilities:", 1); @@ -8846,7 +8752,7 @@ int main(void) { } /* Fp^4 is defined as a quadratic extension of Fp^2. */ - if (fp_prime_get_qnr()) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 4)) { util_print("\n-- Quartic extension: (i + %d) as QNR\n", fp2_field_get_qnr()); util_banner("Utilities:", 1); @@ -8910,7 +8816,7 @@ int main(void) { } /* Fp^6 is defined as a cubic extension of Fp^2. */ - if (fp_prime_get_qnr() && fp_prime_get_cnr()) { + if (fp_prime_get_qnr() && fp_prime_get_cnr() && (ep_curve_embed() >= 6)) { util_print("\n-- Sextic extension: (i + %d) as CNR\n", fp2_field_get_qnr()); util_banner("Utilities:", 1); @@ -8963,7 +8869,7 @@ int main(void) { } } - if (fp_prime_get_qnr() && (ep_param_embed() >= 8)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 8)) { util_banner("Octic extension: (j) as CNR", 0); util_banner("Utilities:", 1); @@ -9026,7 +8932,7 @@ int main(void) { } /* Only execute these if there is an assigned cubic non-residue. */ - if (fp_prime_get_cnr() && (ep_param_embed() >= 9)) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 9)) { util_print("\n-- Nonic extension: (j + %d) as CNR\n", fp3_field_get_cnr()); util_banner("Utilities:", 1); @@ -9080,7 +8986,7 @@ int main(void) { } if (fp_prime_get_qnr() && fp_prime_get_cnr() && - (ep_param_embed() >= 12) && (ep_param_embed() != 16)) { + (ep_curve_embed() >= 12) && (ep_curve_embed() != 16)) { util_banner("Dodecic extension:", 0); util_banner("Utilities:", 1); @@ -9137,7 +9043,7 @@ int main(void) { } } - if (fp_prime_get_qnr() && (ep_param_embed() >= 16)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 16)) { util_banner("Sextadecic extension:", 0); util_banner("Utilities:", 1); @@ -9199,7 +9105,7 @@ int main(void) { } } - if (fp_prime_get_cnr() && (ep_param_embed() >= 18)) { + if (fp_prime_get_cnr() && (ep_curve_embed() >= 18)) { util_banner("Octdecic extension:", 0); util_banner("Utilities:", 1); @@ -9256,7 +9162,7 @@ int main(void) { } } - if (fp_prime_get_qnr() && (ep_param_embed() >= 24)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 24)) { util_banner("Extension of degree 24:", 0); util_banner("Utilities:", 1); @@ -9313,7 +9219,7 @@ int main(void) { } } - if (fp_prime_get_qnr() && (ep_param_embed() >= 48)) { + if (fp_prime_get_qnr() && (ep_curve_embed() >= 48)) { util_banner("Extension of degree 48:", 0); util_banner("Utilities:", 1); @@ -9370,7 +9276,7 @@ int main(void) { } } - if (fp_prime_get_cnr() && (ep_param_embed() == 54)) { + if (fp_prime_get_cnr() && (ep_curve_embed() == 54)) { util_banner("Extension of degree 54:", 0); util_banner("Utilities:", 1); diff --git a/test/test_pc.c b/test/test_pc.c index cf06c9300..53bfb9e18 100644 --- a/test/test_pc.c +++ b/test/test_pc.c @@ -1488,18 +1488,31 @@ int exponentiation(void) { TEST_CASE("exponentiation is correct") { gt_rand(a); - gt_rand(b); + bn_set_dig(d, 0); + gt_exp(b, a, d); + TEST_ASSERT(gt_is_unity(b), end); + bn_set_dig(d, 1); + gt_exp(b, a, d); + TEST_ASSERT(gt_cmp(a, b) == RLC_EQ, end); + bn_rand_mod(d, n); + RLC_CAT(RLC_GT_LOWER, exp)(b, a, d); + gt_exp(c, a, d); + TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); bn_rand_mod(d, n); + gt_exp(b, a, d); + gt_exp_sec(c, a, d); + TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); + bn_neg(d, d); + gt_exp(b, a, d); + gt_exp_sec(c, a, d); + TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); + gt_rand(b); bn_rand_mod(e, n); gt_exp_sim(c, a, d, b, e); gt_exp(a, a, d); gt_exp(b, b, e); gt_mul(b, a, b); TEST_ASSERT(gt_cmp(b, c) == RLC_EQ, end); - gt_exp_dig(b, a, 0); - TEST_ASSERT(gt_is_unity(b), end); - gt_exp_dig(b, a, 1); - TEST_ASSERT(gt_cmp(a, b) == RLC_EQ, end); bn_rand(d, RLC_POS, RLC_DIG); gt_exp(b, a, d); gt_exp_dig(c, a, d->dp[0]); diff --git a/test/test_pp.c b/test/test_pp.c index 6af9e2bab..56e2cd695 100644 --- a/test/test_pp.c +++ b/test/test_pp.c @@ -3927,7 +3927,7 @@ int main(void) { util_banner("Arithmetic", 1); - if (ep_param_embed() == 1) { + if (ep_curve_embed() == 1) { if (doubling1() != RLC_OK) { core_clean(); return 1; @@ -3944,7 +3944,7 @@ int main(void) { } } - if (ep_param_embed() == 2) { + if (ep_curve_embed() == 2) { if (doubling2() != RLC_OK) { core_clean(); return 1; @@ -3961,7 +3961,7 @@ int main(void) { } } - if (ep_param_embed() == 8) { + if (ep_curve_embed() == 8) { if (doubling8() != RLC_OK) { core_clean(); return 1; @@ -3978,7 +3978,7 @@ int main(void) { } } - if (ep_param_embed() == 12) { + if (ep_curve_embed() == 12) { if (doubling12() != RLC_OK) { core_clean(); return 1; @@ -3995,7 +3995,7 @@ int main(void) { } } - if (ep_param_embed() == 16) { + if (ep_curve_embed() == 16) { if (doubling16() != RLC_OK) { core_clean(); return 1; @@ -4012,7 +4012,7 @@ int main(void) { } } - if (ep_param_embed() == 18) { + if (ep_curve_embed() == 18) { if (doubling18() != RLC_OK) { core_clean(); return 1; @@ -4029,7 +4029,7 @@ int main(void) { } } - if (ep_param_embed() == 24) { + if (ep_curve_embed() == 24) { if (doubling24() != RLC_OK) { core_clean(); return 1; @@ -4046,7 +4046,7 @@ int main(void) { } } - if (ep_param_embed() == 48) { + if (ep_curve_embed() == 48) { if (doubling48() != RLC_OK) { core_clean(); return 1; @@ -4063,7 +4063,7 @@ int main(void) { } } - if (ep_param_embed() == 54) { + if (ep_curve_embed() == 54) { if (doubling54() != RLC_OK) { core_clean(); return 1; diff --git a/tools/run-pairings.sh b/tools/run-pairings.sh index 0f091790f..39a659e24 100755 --- a/tools/run-pairings.sh +++ b/tools/run-pairings.sh @@ -1,17 +1,33 @@ set -e for script in preset/x64-pbc-*; do - file=${script##*/} - file=${file%.sh} - echo target-$file - mkdir -p target-$file - cd target-$file - ../$script ../ - make - ./bin/test_fpx && ./bin/test_pc - if [ $? -ne 0 ]; then - echo "FAILED: target-$file" - exit 1 - fi - cd .. + file=${script##*/} + file=${file%.sh} + echo target-$file + mkdir -p target-$file + cd target-$file + ../$script ../ + make + ./bin/test_fpx && ./bin/test_pc + if [ $? -ne 0 ]; then + echo "FAILED: target-$file" + exit 1 + fi + cd .. +done + +for script in preset/gmp-pbc-*; do + file=${script##*/} + file=${file%.sh} + echo target-$file + mkdir -p target-$file + cd target-$file + ../$script ../ + make + ./bin/test_fpx && ./bin/test_pc + if [ $? -ne 0 ]; then + echo "FAILED: target-$file" + exit 1 + fi + cd .. done