diff --git a/src/crypto/zarcanum.h b/src/crypto/zarcanum.h index ac517395..5b8e6d48 100644 --- a/src/crypto/zarcanum.h +++ b/src/crypto/zarcanum.h @@ -108,15 +108,77 @@ namespace crypto // == // u_secrets[j] * (blinded_asset_ids[j] + U) + g_secrets[j] * G + const size_t n = u_secrets.size(); + CHECK_AND_ASSERT_MES(n == g_secrets.size(), false, ""); + CHECK_AND_ASSERT_MES(n == amount_commitments.size(), false, ""); + CHECK_AND_ASSERT_MES(n == amount_commitments_for_rp_aggregation.size(), false, ""); + CHECK_AND_ASSERT_MES(n == blinded_asset_ids.size(), false, ""); + + result.amount_commitments_for_rp_aggregation.clear(); + result.y0s.clear(); + result.y1s.clear(); + + crypto::scalar_vec_t r0, r1; + r0.resize_and_make_random(n); + r1.resize_and_make_random(n); + + std::vector asset_tag_plus_U_vec(n); + for(size_t j = 0; j < n; ++j) + asset_tag_plus_U_vec[j] = blinded_asset_ids[j] + crypto::c_point_U; + + std::vector R(n); + for(size_t j = 0; j < n; ++j) + R[j].assign_mul_plus_G(u_secrets[j], asset_tag_plus_U_vec[j], g_secrets[j]); + + crypto::hash_helper_t::hs_t hash_calculator(1 + 3 * n); + hash_calculator.add_hash(m); + hash_calculator.add_points_array(amount_commitments); + hash_calculator.add_points_array(amount_commitments_for_rp_aggregation); + hash_calculator.add_points_array(R); + result.c = hash_calculator.calc_hash(); + + for(size_t j = 0; j < n; ++j) + { + result.y0s.emplace_back(r0[j] - result.c * u_secrets[j]); + result.y1s.emplace_back(r1[j] - result.c * g_secrets[j]); + result.amount_commitments_for_rp_aggregation.emplace_back((crypto::c_scalar_1div8 * amount_commitments_for_rp_aggregation[j]).to_public_key()); + } return false; } - inline bool verify_vector_UG_aggregation_proof(const hash& m, const std::vector amount_commitments, const std::vector blinded_asset_ids, + inline bool verify_vector_UG_aggregation_proof(const hash& m, const std::vector amount_commitments_1div8, const std::vector blinded_asset_ids_1div8, const vector_UG_aggregation_proof& sig, uint8_t* p_err = nullptr) { - return false; + const size_t n = amount_commitments_1div8.size(); + CHECK_AND_ASSERT_MES(n > 0, false, ""); + CHECK_AND_ASSERT_MES(blinded_asset_ids_1div8.size() == n, false, ""); + CHECK_AND_ASSERT_MES(sig.amount_commitments_for_rp_aggregation.size() == n, false, ""); + CHECK_AND_ASSERT_MES(sig.y0s.size() == n, false, ""); + CHECK_AND_ASSERT_MES(sig.y1s.size() == n, false, ""); + + std::vector asset_tag_plus_U_vec(n); + for(size_t j = 0; j < n; ++j) + asset_tag_plus_U_vec[j] = crypto::point_t(*blinded_asset_ids_1div8[j]).modify_mul8() + crypto::c_point_U; + + crypto::hash_helper_t::hs_t hash_calculator(1 + 3 * n); + hash_calculator.add_hash(m); + + std::vector amount_commitments_pt; + for(size_t j = 0; j < n; ++j) + { + crypto::point_t A = crypto::point_t(*amount_commitments_1div8[j]).modify_mul8(); + hash_calculator.add_point(A); + amount_commitments_pt.emplace_back(A); + } + + hash_calculator.add_pub_keys_array(sig.amount_commitments_for_rp_aggregation); + + for(size_t j = 0; j < n; ++j) + hash_calculator.add_pub_key(crypto::point_t(sig.y0s[j] * asset_tag_plus_U_vec[j] + sig.y1s[j] * crypto::c_point_G - sig.c * amount_commitments_pt[j]).to_public_key()); + + return sig.c == hash_calculator.calc_hash(); }