From e763adbf3146da99d669a5804410a11797e6cf18 Mon Sep 17 00:00:00 2001 From: "valery.osheter" Date: Wed, 13 Feb 2019 20:17:32 +0200 Subject: [PATCH] Code updated to rerun the Paillier ciphertext generation procedure used in key generation in every refresh. The previous method used was not secure --- src/mpc_protocols/mpc_ecc_core.cpp | 67 ------------------------- src/mpc_protocols/mpc_ecc_core.h | 29 ----------- src/mpc_protocols/mpc_ecdsa.cpp | 78 +++++++++--------------------- src/mpc_protocols/mpc_ecdsa.h | 8 +-- 4 files changed, 26 insertions(+), 156 deletions(-) diff --git a/src/mpc_protocols/mpc_ecc_core.cpp b/src/mpc_protocols/mpc_ecc_core.cpp index 670e2f7..b19dbce 100644 --- a/src/mpc_protocols/mpc_ecc_core.cpp +++ b/src/mpc_protocols/mpc_ecc_core.cpp @@ -559,73 +559,6 @@ bool zk_ddh_t::v( } - -//----------------------------- zk_paillier_eq_t ----------------- - -void zk_paillier_eq_t::p( - const bn_t& x, const bn_t& r1, const bn_t& r2, - mem_t session_id, - const bn_t& n1, - const bn_t& c1, - const bn_t& n2, - const bn_t& c2) -{ - this->c1 = c1; - this->c2 = c2; - paillier_t paillier1; paillier1.create_pub(n1); - paillier_t paillier2; paillier2.create_pub(n2); - - bn_t mod1 = n1*n1; - bn_t mod2 = n2*n2; - - bn_t alpha = bn_t::rand(n1 + n2); - bn_t d1 = bn_t::rand(n1); - bn_t d2 = bn_t::rand(n2); - - s1 = paillier1.encrypt(alpha, d1); - s2 = paillier2.encrypt(alpha, d2); - - bn_t e = bn_t(sha256_t::hash(n1, n2, c1, c2, s1, s2, session_id)); - - lc = alpha + e * x; - MODULO(mod1) t1 = d1 * r1.pow(e); - MODULO(mod2) t2 = d2 * r2.pow(e); -} - -bool zk_paillier_eq_t::v( - mem_t session_id, - const bn_t& n1, - const bn_t& n2) const -{ - paillier_t paillier1; paillier1.create_pub(n1); - paillier_t paillier2; paillier2.create_pub(n2); - - bn_t mod1 = n1*n1; - bn_t mod2 = n2*n2; - - bn_t e = bn_t(sha256_t::hash(n1, n2, c1, c2, s1, s2, session_id)); - - bn_t v1 = paillier1.encrypt(lc, t1); - bn_t v2 = paillier2.encrypt(lc, t2); - - bn_t v1_test, v2_test; - MODULO(mod1) v1_test = s1 * c1.pow(e); - MODULO(mod2) v2_test = s2 * c2.pow(e); - - if (v1 != v1_test) - { - return false; - } - - if (v2 != v2_test) - { - return false; - } - - return true; -} - - // ----------------- zk_ec_affine_t ---------------- void zk_ec_affine_t::p(const ecc_point_t& P, const ecc_point_t& U, const ecc_point_t& V, const ecc_point_t& U_tag, const ecc_point_t& V_tag, mem_t session_id, const bn_t& s, const bn_t& w, const bn_t& r_tag) { diff --git a/src/mpc_protocols/mpc_ecc_core.h b/src/mpc_protocols/mpc_ecc_core.h index ace758e..a850e34 100644 --- a/src/mpc_protocols/mpc_ecc_core.h +++ b/src/mpc_protocols/mpc_ecc_core.h @@ -132,35 +132,6 @@ struct zk_ddh_t }; -struct zk_paillier_eq_t -{ - bn_t s1, s2; - bn_t lc; - bn_t t1, t2; - bn_t c1, c2; - - void convert(ub::converter_t& converter) - { - converter.convert(s1); - converter.convert(s2); - converter.convert(lc); - converter.convert(t1); - converter.convert(t2); - converter.convert(c1); - converter.convert(c2); - } - - void p(const bn_t& x, const bn_t& r1, const bn_t& r2, - mem_t session_id, - const bn_t& n1, - const bn_t& c1, - const bn_t& n2, - const bn_t& c2); - bool v(mem_t session_id, - const bn_t& n1, - const bn_t& n2) const; -}; - struct zk_ec_affine_t { bn_t e, z1, z2, z3; diff --git a/src/mpc_protocols/mpc_ecdsa.cpp b/src/mpc_protocols/mpc_ecdsa.cpp index 16c6f80..5703dcf 100644 --- a/src/mpc_protocols/mpc_ecdsa.cpp +++ b/src/mpc_protocols/mpc_ecdsa.cpp @@ -118,73 +118,43 @@ error_t ecdsa_create_paillier_t::peer2_step2(ecdsa_share_t& share, mem_t session //------------------------ ecdsa_refresh_paillier_t--------------------------------- -error_t ecdsa_refresh_paillier_t::peer1_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share, const bn_t& delta) +error_t ecdsa_refresh_paillier_t::peer1_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share) { ecurve_t curve = share.get_curve(); + const ecc_generator_point_t& G = curve.generator(); int paillier_size = get_safe_paillier_bits(curve); - share.paillier.generate(paillier_size); - N = share.paillier.get_N(); + crypto::paillier_t& paillier = share.paillier; + paillier.generate(paillier_size); + N = paillier.get_N(); share.r_key = bn_t::rand(N); - const crypto::paillier_t& paillier1 = old_share.paillier; - const crypto::paillier_t& paillier2 = share.paillier; - - bn_t n1 = paillier1.get_N(); - bn_t n2 = paillier2.get_N(); - - bn_t r1 = old_share.r_key; - bn_t r2 = share.r_key; + c_key = share.c_key = paillier.encrypt(share.x, share.r_key); + pi = mpc::ZK_PAILLIER_P_non_interactive(N, paillier.get_phi_N(), session_id); - bn_t c1 = old_share.c_key; - - bn_t temp = paillier1.decrypt(c1); - bn_t c2 = paillier2.encrypt(temp, r2); - - zk_paillier_eq.p(temp, r1, r2, session_id, n1, c1, n2, c2); - pi = ZK_PAILLIER_P_non_interactive(N, paillier2.get_phi_N(), session_id); - share.c_key = c_key = share.paillier.add_scalar(c2, delta); + zk_pdl.p(curve, G * share.x, c_key, paillier, session_id, 1, share.r_key, share.x); return 0; } -error_t ecdsa_refresh_paillier_t::peer2_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share, const bn_t& delta) const +error_t ecdsa_refresh_paillier_t::peer2_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share) const { error_t rv = 0; ecurve_t curve = share.get_curve(); + const ecc_generator_point_t& G = curve.generator(); int paillier_size = get_safe_paillier_bits(curve); if (N.get_bits_count() < paillier_size) return rv = error(E_CRYPTO); - share.c_key = c_key; - share.paillier.create_pub(N); - - if (zk_paillier_eq.c1 != old_share.c_key) - { - return rv = ub::error(E_CRYPTO); - } - - const crypto::paillier_t& paillier1 = old_share.paillier; - const crypto::paillier_t& paillier2 = share.paillier; + if (!mpc::ZK_PAILLIER_V_non_interactive(N, pi, session_id)) return rv = error(E_CRYPTO); + ecc_point_t Q_remote = share.Q_full - G *share.x; + + if (!curve.check(zk_pdl.R)) return rv = error(E_CRYPTO); + if (!zk_pdl.v(curve, Q_remote, c_key, N, session_id, 1)) return rv = error(E_CRYPTO); - bn_t n1 = paillier1.get_N(); - bn_t n2 = paillier2.get_N(); - - if (!ZK_PAILLIER_V_non_interactive(n2, pi, session_id)) return rv = error(E_CRYPTO); - - if (!zk_paillier_eq.v(session_id, n1, n2)) - { - return rv = ub::error(E_CRYPTO); - } - - // recalculate c_key - bn_t new_c_key = paillier2.add_scalar(zk_paillier_eq.c2, delta); - - if (c_key!=new_c_key) - { - return rv = ub::error(E_CRYPTO); - } + share.c_key = c_key; + share.paillier.create_pub(N); return 0; } @@ -388,15 +358,13 @@ error_t ecdsa_sign_t::peer2_step2( bn_t m_tag = bn_t::from_bin(data_to_sign); - //bn_t rho = bn_t::rand((q*q) << 208); // 128 + 80 (needed to ensure statistical closeness, even though over integers) - bn_t rho = bn_t::rand((q*q) << 80); // 80 (need additional noise over q*q due to refresh) + bn_t rho = bn_t::rand(q*q); MODULO(q) u = m_tag / k2; bn_t u2 = rho*q + u; MODULO(q) v = r / k2; bn_t c1 = share.paillier.add_scalar(share.c_key, share.x); - // c1 = share.paillier.add_scalar(c1, q << 208); // 128 + 80 (needed to ensure that is positive, due to slack in range proof) bn_t c2 = share.paillier.mul_scalar(c1, v); out.c3 = share.paillier.add_scalar(c2, u2); @@ -441,7 +409,7 @@ error_t ecdsa_sign_t::peer1_step3( bn_t delta; if (rv = ecdsa_share_t::get_refresh_delta(curve, agree_refresh, delta)) return rv; if (rv = share.refresh_peer1(delta)) return rv; - if (rv = out.refresh_paillier.peer1_step(share, session_id, old_share, delta)) return rv; + if (rv = out.refresh_paillier.peer1_step(share, session_id, old_share)) return rv; } return 0; @@ -467,9 +435,7 @@ error_t ecdsa_sign_t::peer2_step3( if (rv = ecdsa_share_t::get_refresh_delta(curve, agree_refresh, delta)) return rv; if (rv = share.refresh_peer2(delta)) return rv; - const bn_t& order = curve.order(); - bn_t x_delta = bn_t::from_bin(agree_refresh) % order; - if (rv = in.refresh_paillier.peer2_step(share, session_id, old_share, delta)) return rv; + if (rv = in.refresh_paillier.peer2_step(share, session_id, old_share)) return rv; } return 0; @@ -519,7 +485,7 @@ error_t ecdsa_refresh_t::peer1_step2( bn_t delta; if (rv = ecdsa_share_t::get_refresh_delta(curve, agree_refresh, delta)) return rv; if (rv = share.refresh_peer1(delta)) return rv; - if (rv = out.refresh_paillier.peer1_step(share, session_id, old_share, delta)) return rv; + if (rv = out.refresh_paillier.peer1_step(share, session_id, old_share)) return rv; return 0; } @@ -543,7 +509,7 @@ error_t ecdsa_refresh_t::peer2_step2( bn_t delta; if (rv = ecdsa_share_t::get_refresh_delta(curve, agree_refresh, delta)) return rv; if (rv = share.refresh_peer2(delta)) return rv; - if (rv = in.refresh_paillier.peer2_step(share, session_id, old_share, delta)) return rv; + if (rv = in.refresh_paillier.peer2_step(share, session_id, old_share)) return rv; return 0; } diff --git a/src/mpc_protocols/mpc_ecdsa.h b/src/mpc_protocols/mpc_ecdsa.h index 82f4e52..8642347 100644 --- a/src/mpc_protocols/mpc_ecdsa.h +++ b/src/mpc_protocols/mpc_ecdsa.h @@ -56,18 +56,18 @@ struct ecdsa_refresh_paillier_t { bn_t N, c_key; buf_t pi; - zk_paillier_eq_t zk_paillier_eq; + zk_pdl_t zk_pdl; void convert(ub::converter_t& converter) { converter.convert(N); converter.convert(c_key); converter.convert(pi); - converter.convert(zk_paillier_eq); + converter.convert(zk_pdl); } - error_t peer1_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share, const bn_t& delta); - error_t peer2_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share, const bn_t& delta) const; + error_t peer1_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share); + error_t peer2_step(ecdsa_share_t& share, mem_t session_id, const ecdsa_share_t& old_share) const; }; struct ecdsa_create_paillier_t