From d8dde6fb2e90d0ce6bd1312073ef205ec983899b Mon Sep 17 00:00:00 2001 From: "Diego F. Aranha" Date: Tue, 2 Apr 2024 01:14:53 +0200 Subject: [PATCH] Add private version of AMORE protocol. --- bench/bench_cp.c | 26 ++++++++ include/relic_cp.h | 58 ++++++++++++++++++ src/cp/relic_cp_pcdel.c | 132 ++++++++++++++++++++++++++++++++++++++++ test/test_cp.c | 19 ++++++ 4 files changed, 235 insertions(+) diff --git a/bench/bench_cp.c b/bench/bench_cp.c index ea6c96090..6ddb8c378 100644 --- a/bench/bench_cp.c +++ b/bench/bench_cp.c @@ -920,6 +920,32 @@ static void pdprv(void) { BENCH_ADD(cp_lvprv_ver(r, g, r1, e)); } BENCH_END; + BENCH_RUN("cp_amprv_gen (first)") { + BENCH_ADD(cp_amprv_gen(r1, r2[0], r2[1], r2[2], e[0], v1[0], v2[0], 1)); + } BENCH_END; + + BENCH_RUN("cp_amprv_ask") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_amprv_ask(u1, u2, p, q, r1, r2[0], r2[1], v1[0], v2[0])); + } BENCH_END; + + BENCH_RUN("cp_amprv_ans") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_amprv_ans(r, g[0], r1, u1, u2)); + } BENCH_END; + + BENCH_RUN("cp_amprv_ver") { + g1_rand(p); + g2_rand(q); + BENCH_ADD(cp_amprv_ver(r, g[0], r2[0], e[0])); + } BENCH_END; + + BENCH_RUN("cp_amprv_gen") { + BENCH_ADD(cp_amprv_gen(r1, r2[0], r2[1], r2[2], e[0], v1[0], v2[0], 1)); + } BENCH_END; + bn_free(r1); g1_free(p); g2_free(q); diff --git a/include/relic_cp.h b/include/relic_cp.h index 0051044d0..59b5ea62d 100644 --- a/include/relic_cp.h +++ b/include/relic_cp.h @@ -1423,6 +1423,64 @@ int cp_ampub_ans(gt_t g[2], const g1_t p, const g2_t q, const g1_t v1, */ int cp_ampub_ver(gt_t r, gt_t e, const gt_t g[2], const bn_t c); +/** + * Generate parameters for the AMORE pairing delegation protocol with private + * inputs. + * + * @param[out] c - the delta value binding randomness together. + * @param[out] c - the challenge. + * @param[out] r - the randomness. + * @param[out] x - the secret value preserved across iterations. + * @param[out] e - the precomputed value in G_T. + * @param[out] u - the U precomputed value in G_1. + * @param[out] v - the V precomputed value in G_2. + * @param[in] first - the flag to indicate if the first iteration. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_amprv_gen(bn_t d, bn_t c, bn_t r, bn_t x, gt_t e, g1_t u, g2_t v, + int first); + +/** + * Execute the client-side request for the AMORE pairing delegation protocol. + * + * @param[out] a - the blinded elements in G_1. + * @param[out] b - the blinded elements in G_2. + * @param[in] p - the first argument of the pairing. + * @param[in] q - the second argument of the pairing. + * @param[in] d - the delta value generated at setup. + * @param[in] c - the challenge. + * @param[in] r - the randomness. + * @param[in] u - the U precomputed value in G_1. + * @param[in] v - the V precomputed value in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_amprv_ask(g1_t a[2], g2_t b[2], const g1_t p, const g2_t q, const bn_t d, + const bn_t c, const bn_t r, const g1_t u, const g2_t v); + +/** + * Execute the server-side response for the AMORE pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[out] g - the other group element returned by the server. + * @param[in] d - the delta value generated at setup. + * @param[in] a - the blinded elements in G_1. + * @param[in] b - the blinded elements in G_2. + * @return RLC_OK if no errors occurred, RLC_ERR otherwise. + */ +int cp_amprv_ans(gt_t r, gt_t g, const bn_t d, const g1_t a[2], + const g2_t b[2]); + +/** + * Verifies the result of the AMORE pairing delegation protocol. + * + * @param[out] r - the result of the computation. + * @param[in] g - the other group element returned by the server. + * @param[in] c - the challenge. + * @param[in] e - the precomputed value in G_T. + * @return a boolean value indicating if the computation is correct. + */ +int cp_amprv_ver(gt_t r, const gt_t g, const bn_t c, const gt_t e); + /** * Generates a master key for the SOKAKA identity-based non-interactive * authenticated key agreement protocol. diff --git a/src/cp/relic_cp_pcdel.c b/src/cp/relic_cp_pcdel.c index ef86d6eec..4949e8655 100644 --- a/src/cp/relic_cp_pcdel.c +++ b/src/cp/relic_cp_pcdel.c @@ -641,3 +641,135 @@ int cp_ampub_ver(gt_t r, gt_t e, const gt_t g[2], const bn_t c) { } return result; } + +int cp_amprv_gen(bn_t d, bn_t c, bn_t r, bn_t x, gt_t e, g1_t u, g2_t v, + int first) { + bn_t n, t; + int result = RLC_OK; + + bn_null(n); + bn_null(t); + + RLC_TRY { + bn_new(n); + bn_new(t); + + pc_get_ord(n); + if (first) { + bn_rand_mod(x, n); + gt_get_gen(e); + gt_exp(e, e, x); + bn_rand_frb(c, &(core_get()->par), n, RAND_DIST); + } else { + bn_rand_frb(c, &(core_get()->par), n, RAND_DIST + ep_param_level()); + } + bn_rand_mod(t, n); + bn_rand_mod(r, n); + g1_mul_gen(u, t); + bn_mul(d, c, r); + bn_mod(d, d, n); + bn_mul(d, d, t); + bn_mod(d, d, n); + bn_mod_inv(d, d, n); + bn_mul(d, d, x); + bn_mod(d, d, n); + bn_mod_inv(t, t, n); + bn_mul(t, t, x); + bn_mod(t, t, n); + g2_mul_gen(v, t); + } + RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + bn_free(n); + bn_free(t); + } + return result; +} + +int cp_amprv_ask(g1_t a[2], g2_t b[2], const g1_t p, const g2_t q, const bn_t d, + const bn_t c, const bn_t r, const g1_t u, const g2_t v) { + int result = RLC_OK; + bn_t n; + + bn_null(n); + + RLC_TRY { + bn_new(n); + + pc_get_ord(n); + g1_sub(a[0], u, p); + g1_mul(a[0], a[0], r); + g2_sub(b[0], v, q); + g2_mul(b[1], q, c); + bn_mod_inv(n, c, n); + g1_mul(a[1], p, n); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + bn_free(n); + } + + return result; +} + +int cp_amprv_ans(gt_t r, gt_t g, const bn_t d, const g1_t a[2], + const g2_t b[2]) { + int result = RLC_OK; + g1_t _p[2]; + g2_t _q[2]; + + g1_null(_p[0]); + g1_null(_p[1]); + g2_null(_q[0]); + g2_null(_q[1]); + + RLC_TRY { + g1_new(_p[0]); + g1_new(_p[1]); + g2_new(_q[0]); + g2_new(_q[1]); + + g1_copy(_p[0], a[0]); + g2_mul_gen(_q[0], d); + g1_copy(_p[1], a[1]); + g2_copy(_q[1], b[0]); + pc_map_sim(g, _p, _q, 2); + pc_map(r, a[1], b[1]); + } RLC_CATCH_ANY { + RLC_THROW(ERR_CAUGHT); + } RLC_FINALLY { + g1_free(_p[0]); + g1_free(_p[1]); + g2_free(_q[0]); + g2_free(_q[1]); + } + return result; +} + +int cp_amprv_ver(gt_t r, const gt_t g, const bn_t c, const gt_t e) { + int result = 1; + gt_t t; + + gt_null(t); + + RLC_TRY { + gt_new(t); + + result &= gt_is_valid(r); + + gt_exp(t, g, c); + gt_mul(t, t, r); + + if (!result || gt_cmp(t, e) != RLC_EQ) { + gt_set_unity(r); + } + } RLC_CATCH_ANY { + result = RLC_ERR; + } + RLC_FINALLY { + gt_free(t); + } + return result; +} \ No newline at end of file diff --git a/test/test_cp.c b/test/test_cp.c index 75033805c..b8bc9951f 100644 --- a/test/test_cp.c +++ b/test/test_cp.c @@ -1266,6 +1266,25 @@ static int pdprv(void) { pc_map(e[0], p, q); TEST_ASSERT(gt_cmp(r, e[0]) == RLC_EQ, end); } TEST_END; + + TEST_CASE("amortized delegated pairing with private inputs is correct") { + TEST_ASSERT(cp_amprv_gen(r1, r2[0], r2[1], r2[2], e[0], v1[0], v2[0], 1) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_amprv_ask(u1, u2, p, q, r1, r2[0], r2[1], v1[0], v2[0]) == RLC_OK, end); + TEST_ASSERT(cp_amprv_ans(r, g[0], r1, u1, u2) == RLC_OK, end); + TEST_ASSERT(cp_amprv_ver(r, g[0], r2[0], e[0]) == 1, end); + pc_map(g[0], p, q); + TEST_ASSERT(gt_cmp(r, g[0]) == RLC_EQ, end); + TEST_ASSERT(cp_amprv_gen(r1, r2[0], r2[1], r2[2], e[0], v1[0], v2[0], 0) == RLC_OK, end); + g1_rand(p); + g2_rand(q); + TEST_ASSERT(cp_amprv_ask(u1, u2, p, q, r1, r2[0], r2[1], v1[0], v2[0]) == RLC_OK, end); + TEST_ASSERT(cp_amprv_ans(r, g[0], r1, u1, u2) == RLC_OK, end); + TEST_ASSERT(cp_amprv_ver(r, g[0], r2[0], e[0]) == 1, end); + pc_map(g[0], p, q); + TEST_ASSERT(gt_cmp(r, g[0]) == RLC_EQ, end); + } TEST_END; } RLC_CATCH_ANY { RLC_ERROR(end); }