diff --git a/bench/bench_fpx.c b/bench/bench_fpx.c index 4deaa7738..215f80361 100644 --- a/bench/bench_fpx.c +++ b/bench/bench_fpx.c @@ -2060,7 +2060,7 @@ static void arith12(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 12) { + if (ep_curve_is_pairf() && ep_curve_embed() == 12) { BENCH_RUN("fp12_exp_cyc (gls)") { fp12_rand(a); fp12_conv_cyc(a, a); @@ -2347,7 +2347,7 @@ static void arith16(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 16) { + if (ep_curve_is_pairf() && ep_curve_embed() == 16) { BENCH_RUN("fp16_exp_cyc (gls)") { fp16_rand(a); fp16_conv_cyc(a, a); @@ -2717,7 +2717,7 @@ static void arith18(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 18) { + if (ep_curve_is_pairf() && ep_curve_embed() == 18) { BENCH_RUN("fp18_exp_cyc (gls)") { fp18_rand(a); fp18_conv_cyc(a, a); @@ -3050,7 +3050,7 @@ static void arith24(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 24) { + if (ep_curve_is_pairf() && ep_curve_embed() == 24) { BENCH_RUN("fp24_exp_cyc (gls)") { fp24_rand(a); fp24_conv_cyc(a, a); @@ -3428,7 +3428,7 @@ static void arith48(void) { } BENCH_END; - if (ep_curve_is_pairf() && ep_param_embed() == 48) { + if (ep_curve_is_pairf() && ep_curve_embed() == 48) { BENCH_RUN("fp48_exp_cyc (gls)") { fp48_rand(a); fp48_conv_cyc(a, a); @@ -3922,7 +3922,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(); @@ -3931,7 +3931,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(); @@ -3940,7 +3940,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(); @@ -3949,7 +3949,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(); @@ -3959,7 +3959,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(); @@ -3969,7 +3969,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(); @@ -3978,7 +3978,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(); @@ -3987,7 +3987,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 ee89804fe..bb040c6f4 100755 --- a/bench/bench_pc.c +++ b/bench/bench_pc.c @@ -629,7 +629,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); 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/include/relic_ep.h b/include/relic_ep.h index 2a773f5db..9e9a6efc5 100644 --- a/include/relic_ep.h +++ b/include/relic_ep.h @@ -744,7 +744,7 @@ int ep_param_level(void); /** * Returns the embedding degree of the currently configured elliptic curve. */ -int ep_param_embed(void); +int ep_curve_embed(void); /** * Tests if a point on a prime elliptic curve is at the infinity. diff --git a/include/relic_label.h b/include/relic_label.h index 1b4b5404f..e030b9128 100644 --- a/include/relic_label.h +++ b/include/relic_label.h @@ -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 @@ -1037,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) diff --git a/src/ep/relic_ep_curve.c b/src/ep/relic_ep_curve.c index e18fc093c..fd5769ab6 100644 --- a/src/ep/relic_ep_curve.c +++ b/src/ep/relic_ep_curve.c @@ -521,3 +521,33 @@ 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; +} \ No newline at end of file diff --git a/src/ep/relic_ep_param.c b/src/ep/relic_ep_param.c index e4c5334fc..c2b9a25ed 100644 --- a/src/ep/relic_ep_param.c +++ b/src/ep/relic_ep_param.c @@ -1863,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/fpx/relic_fpx_cyc.c b/src/fpx/relic_fpx_cyc.c index 57d41efc4..ad97c903a 100644 --- a/src/fpx/relic_fpx_cyc.c +++ b/src/fpx/relic_fpx_cyc.c @@ -937,7 +937,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); diff --git a/src/pc/relic_pc_exp.c b/src/pc/relic_pc_exp.c index 271bb0d29..745c1c1f0 100644 --- a/src/pc/relic_pc_exp.c +++ b/src/pc/relic_pc_exp.c @@ -254,6 +254,138 @@ void gt_exp_imp(gt_t c, const gt_t a, const bn_t b, size_t f) { } } +/** + * 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_gls(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 */ /*============================================================================*/ @@ -393,7 +525,7 @@ void gt_exp_sec(gt_t c, const gt_t a, const bn_t b) { size_t f = 0; - switch (ep_param_embed()) { + switch (ep_curve_embed()) { case 1: case 2: case 8: diff --git a/test/test_fpx.c b/test/test_fpx.c index 3c0da4afb..727aea007 100644 --- a/test/test_fpx.c +++ b/test/test_fpx.c @@ -4677,7 +4677,7 @@ static int cyclotomic12(void) { TEST_ASSERT(fp12_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 12) { + if (ep_curve_is_pairf() && ep_curve_embed() == 12) { TEST_CASE("cyclotomic exponentiation in subgroup is correct") { fp12_rand(a); pp_exp_k12(a, a); @@ -5407,7 +5407,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); @@ -6177,7 +6177,7 @@ static int cyclotomic18(void) { TEST_ASSERT(fp18_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 18) { + if (ep_curve_is_pairf() && ep_curve_embed() == 18) { TEST_CASE("cyclotomic exponentiation in subgroup is correct") { fp18_rand(a); pp_exp_k18(a, a); @@ -6953,7 +6953,7 @@ static int cyclotomic24(void) { TEST_ASSERT(fp24_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 24) { + if (ep_curve_is_pairf() && ep_curve_embed() == 24) { TEST_CASE("cyclotomic exponentiation in subgroup is correct") { fp24_rand(a); pp_exp_k24(a, a); @@ -7768,7 +7768,7 @@ static int cyclotomic48(void) { TEST_ASSERT(fp48_cmp(b, c) == RLC_EQ, end); } TEST_END; - if (ep_curve_is_pairf() && ep_param_embed() == 48) { + if (ep_curve_is_pairf() && ep_curve_embed() == 48) { TEST_CASE("cyclotomic exponentiation in subgroup is correct") { fp48_rand(a); pp_exp_k48(a, a); @@ -8781,7 +8781,7 @@ int main(void) { } /* Only execute these if there is an assigned cubic non-residue. */ - if (fp_prime_get_cnr() && (ep_param_embed() >= 3)) { + 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); @@ -8844,7 +8844,7 @@ int main(void) { } /* Fp^4 is defined as a quadratic extension of Fp^2. */ - if (fp_prime_get_qnr() && (ep_param_embed() >= 4)) { + 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); @@ -8908,7 +8908,7 @@ int main(void) { } /* Fp^6 is defined as a cubic extension of Fp^2. */ - if (fp_prime_get_qnr() && fp_prime_get_cnr() && (ep_param_embed() >= 6)) { + 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); @@ -8961,7 +8961,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); @@ -9024,7 +9024,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); @@ -9078,7 +9078,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); @@ -9135,7 +9135,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); @@ -9197,7 +9197,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); @@ -9254,7 +9254,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); @@ -9311,7 +9311,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); @@ -9368,7 +9368,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_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;