diff --git a/bench/bench_cp.c b/bench/bench_cp.c index afb65bfc4..555a65c98 100644 --- a/bench/bench_cp.c +++ b/bench/bench_cp.c @@ -949,7 +949,7 @@ static void pdprv(void) { bn_t r1, r2[3], ls[AGGS * AGGS], cs[AGGS], ks[AGGS]; g1_t fs[AGGS], p[AGGS * AGGS], u1[2], v1[3]; g2_t q[AGGS * AGGS], u2[2], v2[4], w2[4], ds[AGGS * AGGS], bs[AGGS], rs[AGGS * AGGS]; - gt_t e[2], r, ts[AGGS], g[3 * AGGS + 1]; + gt_t e[2], r, ts[AGGS + 1], g[3 * AGGS + 1]; bn_null(r1); gt_null(r); @@ -976,8 +976,7 @@ static void pdprv(void) { g2_null(ds[i]) g2_null(rs[i]) } - bn_null(ls[AGGS]); - g2_null(rs[AGGS]); + gt_null(ts[AGGS]); bn_new(r1); gt_new(r); @@ -1024,6 +1023,7 @@ static void pdprv(void) { g2_new(bs[i]); gt_new(ts[i]); } + gt_new(ts[AGGS]); BENCH_RUN("cp_pdprv_gen") { BENCH_ADD(cp_pdprv_gen(r1, r2, u1, u2, v2, e)); @@ -1069,6 +1069,22 @@ static void pdprv(void) { BENCH_ADD(cp_lvprv_ver(r, g, r1, e)); } BENCH_END; + BENCH_RUN("cp_mvbat_gen (AGGS)") { + BENCH_ADD(cp_mvbat_gen(r1, fs, AGGS)); + } BENCH_END; + + BENCH_RUN("cp_mvbat_ask (AGGS)") { + BENCH_ADD(cp_mvbat_ask(u1[0], fs, u2[0], g, r1, p, q[0], fs, AGGS)); + } BENCH_END; + + BENCH_RUN("cp_mvbat_ans (AGGS)") { + BENCH_ADD(cp_mvbat_ans(ts, u1[0], fs, u2[0], AGGS)); + } BENCH_END; + + BENCH_RUN("cp_mvbat_ver (AGGS)") { + BENCH_ADD(cp_mvbat_ver(g, ts, g, AGGS)); + } BENCH_END; + BENCH_RUN("cp_ambat_gen (AGGS)") { BENCH_ADD(cp_ambat_gen(r1, u1[0], u2[0], e[0])); } BENCH_END; @@ -1135,6 +1151,7 @@ static void pdprv(void) { g2_free(bs[i]); gt_free(ts[i]); } + gt_free(ts[AGGS]); } static void sokaka(void) { diff --git a/include/relic_cp.h b/include/relic_cp.h index 8d9cab8ce..aef5646eb 100644 --- a/include/relic_cp.h +++ b/include/relic_cp.h @@ -1436,6 +1436,60 @@ int cp_amore_ans(gt_t g[2], const bn_t d, const g1_t a1, const g2_t b1, int cp_amore_ver(gt_t r, const gt_t g[2], const bn_t c, const gt_t e, int priva, int privb); +/** + * Generates parameters for the Mefenza-Vergnaud (MV) delegated batch pairing + * protocol. + * + * @param[out] r - the randomness. + * @param[out] x - the masks in G_1. + * @param[out] m - the number of pairings to delegate in a batch. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_mvbat_gen(bn_t r, g1_t *x, size_t m); + +/** + * Executes the client-side request for the MV batch pairing delegation + * protocol. + * + * @param[out] p0 - the challenge point in G_1. + * @param[out] ps - the group elements computed by the client. + * @param[out] q0 - the challenge point in G_2. + * @param[out] e - the pairings computed by the client. + * @param[in] r - the randomness. + * @param[in] p - the first arguments of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] x - the masks in G_1. + * @param[in] m - the number of pairings delegated in the batch. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_mvbat_ask(g1_t p0, g1_t *ps, g2_t q0, gt_t *e, const bn_t r, + const g1_t *p, const g2_t q, const g1_t *x, size_t m); + +/** + * Executes the server-side response for the MV batch pairing delegation + * protocol. + * + * @param[out] as - the group elements computed by the server. + * @param[in] p0 - the challenge point in G_1. + * @param[in] ps - the group elements computed by the client. + * @param[in] q0 - the challenge point in G_2. + * @param[in] m - the number of pairings delegated in the batch. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_mvbat_ans(gt_t *as, const g1_t p0, const g1_t *ps, const g2_t q0, + size_t m); + +/** + * Verifies the result of the MV batch pairing delegation protocol. + * + * @param[out] rs - the results of the computation. + * @param[in] as - the group elements returned by the server. + * @param[in] e - the pairings computed by the client. + * @param[in] m - the number of pairings delegated in the batch. + * @return a boolean value indicating if the computation is correct. + */ +int cp_mvbat_ver(gt_t *rs, const gt_t *as, const gt_t *e, size_t m); + /** * Generates parameters for the AMORE batch pairing delegation protocol. * diff --git a/src/cp/relic_cp_pcdel.c b/src/cp/relic_cp_pcdel.c index e13301d73..996ca9006 100644 --- a/src/cp/relic_cp_pcdel.c +++ b/src/cp/relic_cp_pcdel.c @@ -711,6 +711,138 @@ int cp_amore_ver(gt_t r, const gt_t g[2], const bn_t c, const gt_t e, return result; } +int cp_mvbat_gen(bn_t r, g1_t *x, size_t m) { + bn_t n; + int result = RLC_OK; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + bn_rand_mod(r, n); + for (size_t i = 0; i < m; i++) { + g1_rand(x[i]); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } RLC_FINALLY { + bn_free(n); + } + + return result; +} + +int cp_mvbat_ask(g1_t p0, g1_t *ps, g2_t q0, gt_t *e, const bn_t r, + const g1_t *p, const g2_t q, const g1_t *x, size_t m) { + bn_t prime, n; + g1_t t, u; + int result = RLC_OK; + + bn_null(n); + bn_null(prime); + g1_null(t); + g1_null(u); + + RLC_TRY { + bn_new(n); + bn_new(prime); + g1_new(t); + g1_new(u); + + pc_get_ord(n); + dv_copy(prime->dp, fp_prime_get(), RLC_FP_DIGS); + prime->sign = RLC_POS; + prime->used = RLC_FP_DIGS; + bn_mod(prime, prime, n); + + g1_rand(p0); + bn_mod_inv(n, r, n); + g2_mul(q0, q, n); + + pc_map(e[0], p0, q0); + for (size_t i = 0; i < m; i++) { + pc_map(e[i + 1], x[i], q0); + gt_inv(e[i + 1], e[i + 1]); + g1_mul(t, p[i], r); + g1_add(ps[i], x[i], t); + } + g1_norm_sim(ps, ps, m); + + g1_set_infty(u); + for (size_t i = 0; i < RLC_MIN(m, pc_param_level()); i++) { + g1_mul_dig(t, ps[i], i + 1); + g1_add(u, u, t); + } + g1_norm(u, u); + g1_mul(u, u, prime); + g1_add(p0, p0, u); + g1_norm(p0, p0); + } RLC_CATCH_ANY { + result = RLC_ERR; + } RLC_FINALLY { + bn_free(n); + bn_free(prime); + g1_free(t); + g1_free(u); + } + + return result; +} + +int cp_mvbat_ans(gt_t *as, const g1_t p0, const g1_t *ps, const g2_t q0, + size_t m) { + pc_map(as[0], p0, q0); + for (size_t i = 0; i < m; i++) { + pc_map(as[i + 1], ps[i], q0); + } + + return RLC_OK; +} + +int cp_mvbat_ver(gt_t *rs, const gt_t *as, const gt_t *e, size_t m) { + gt_t t, alpha; + int result = 1; + + gt_null(t); + gt_null(alpha); + + RLC_TRY { + gt_new(t); + gt_new(alpha); + + for (size_t i = 0; i <= m; i++) { + result &= gt_is_valid(as[i]); + } + + gt_copy(alpha, e[0]); + for (size_t i = 1; i <= RLC_MIN(m, pc_param_level()); i++) { + gt_exp_dig(t, as[i], i); + gt_frb(t, t, 1); + gt_mul(alpha, alpha, t); + } + if (!result|| (gt_cmp(alpha, as[0]))) { + printf("eita\n"); + for (size_t i = 0; i < m; i++) { + gt_set_unity(rs[i]); + } + } else { + for (size_t i = 0; i < m; i++) { + gt_mul(rs[i], as[i + 1], e[i + 1]); + } + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } RLC_FINALLY { + gt_free(t); + gt_free(alpha); + } + + return result; +} + + int cp_ambat_gen(bn_t r, g1_t u, g2_t v, gt_t e) { bn_t n, t; int result = RLC_OK; diff --git a/test/test_cp.c b/test/test_cp.c index e042448e2..c0d907490 100644 --- a/test/test_cp.c +++ b/test/test_cp.c @@ -1328,7 +1328,7 @@ static int pdprd(void) { bn_t x, t, r, ls[AGGS * AGGS], cs[AGGS], ks[AGGS]; g1_t fs[AGGS], p[AGGS * AGGS], u1, v1; g2_t q[AGGS * AGGS], u2, v2, w2, rs[AGGS * AGGS], ds[AGGS * AGGS], bs[AGGS]; - gt_t e, ts[AGGS], g[3 * AGGS + 1]; + gt_t e, ts[AGGS + 1], g[3 * AGGS + 1]; bn_null(t); bn_null(x); @@ -1378,8 +1378,25 @@ static int pdprd(void) { g2_new(bs[i]); gt_new(ts[i]); } + gt_null(ts[AGGS]); + gt_new(ts[AGGS]); - TEST_CASE("batch delegated pairing with (n - 1) public inputs is correct") { + TEST_CASE("delegated batch delegated pairing is correct") { + TEST_ASSERT(cp_mvbat_gen(r, fs, AGGS) == RLC_OK, end); + for (size_t i = 0; i < AGGS; i++) { + g1_rand(p[i]); + } + g2_rand(q[0]); + TEST_ASSERT(cp_mvbat_ask(u1, fs, u2, g, r, p, q[0], fs, AGGS) == RLC_OK, end); + TEST_ASSERT(cp_mvbat_ans(ts, u1, fs, u2, AGGS) == RLC_OK, end); + TEST_ASSERT(cp_mvbat_ver(g, ts, g, AGGS) == 1, end); + for (size_t i = 0; i < AGGS; i++) { + pc_map(e, p[i], q[0]); + TEST_ASSERT(gt_cmp(e, g[i]) == RLC_EQ, end); + } + } TEST_END; + + TEST_CASE("amortized batch delegated pairing is correct") { TEST_ASSERT(cp_ambat_gen(r, u1, u2, e) == RLC_OK, end); for (size_t i = 0; i < AGGS; i++) { g1_rand(p[i]); @@ -1442,6 +1459,7 @@ static int pdprd(void) { g2_free(bs[i]); gt_free(ts[i]); } + gt_free(ts[AGGS]); return code; } @@ -2518,7 +2536,7 @@ int main(void) { } util_banner("Tests for the CP module", 0); - +#if 0 #if defined(WITH_BN) util_banner("Protocols based on integer factorization:\n", 0); if (rsa() != RLC_OK) { @@ -2608,7 +2626,7 @@ int main(void) { } } #endif - +#endif #if defined(WITH_PC) util_banner("Protocols based on pairings:\n", 0); if (pc_param_set_any() == RLC_OK) {