1
0
Fork 0
forked from lthn/blockchain

CLSAG 5-layers GGXXG has been debugged + test added

This commit is contained in:
sowle 2023-03-22 03:14:45 +01:00
parent 06c0394b67
commit 1a53806642
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 157 additions and 4 deletions

View file

@ -998,7 +998,7 @@ namespace crypto
hsc.add_point(sig.r_x[i] * c_point_X + c_prev * W_pub_keys_x[i]);
hsc.add_point(sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x);
c_prev = hsc.calc_hash(); // c_{i + 1}
DBG_PRINT("c[" << i + 1 << "] = Hs(ih, " << sig.r_g[i] * c_point_G + c_prev * W_pub_keys_g[i] << ", " << sig.r_g[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_g << ", " << sig.r_x[i] * c_point_X + c_prev * W_pub_keys_x[i] << ", " << sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x << ")");
//DBG_PRINT("c[" << i + 1 << "] = Hs(ih, " << sig.r_g[i] * c_point_G + c_prev * W_pub_keys_g[i] << ", " << sig.r_g[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_g << ", " << sig.r_x[i] * c_point_X + c_prev * W_pub_keys_x[i] << ", " << sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x << ")");
}
DBG_PRINT("c[" << secret_index << "] = " << c_prev);
@ -1141,7 +1141,7 @@ namespace crypto
DBG_PRINT("c[0] = " << c_prev);
for(size_t i = 0; i < ring_size; ++i)
{
hsc.add_32_chars(CRYPTO_HDS_CLSAG_GGXG_CHALLENGE);
hsc.add_32_chars(CRYPTO_HDS_CLSAG_GGXXG_CHALLENGE);
hsc.add_hash(input_hash);
hsc.add_point(sig.r_g[i] * c_point_G + c_prev * W_pub_keys_g[i]);
hsc.add_point(sig.r_g[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_g);
@ -1149,7 +1149,7 @@ namespace crypto
hsc.add_point(sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x);
c_prev = hsc.calc_hash(); // c_{i + 1}
DBG_PRINT("c[" << i + 1 << "] = " << c_prev);
DBG_PRINT("c[" << i + 1 << "] = Hs(ih, " << sig.r_g[i] * c_point_G + c_prev * W_pub_keys_g[i] << ", " << sig.r_g[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_g << ", " << sig.r_x[i] * c_point_X + c_prev * W_pub_keys_x[i] << ", " << sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x << ")");
//DBG_PRINT("c[" << i + 1 << "] = Hs(ih, " << sig.r_g[i] * c_point_G + c_prev * W_pub_keys_g[i] << ", " << sig.r_g[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_g << ", " << sig.r_x[i] * c_point_X + c_prev * W_pub_keys_x[i] << ", " << sig.r_x[i] * hash_helper_t::hp(ring[i].stealth_address) + c_prev * W_key_image_x << ")");
}
return c_prev == sig.c;

View file

@ -537,4 +537,157 @@ TEST(clsag_ggxg, basics)
ASSERT_TRUE(cc.verify());
return true;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// CLSAG GGXXG
//
struct clsag_ggxxg_sig_check_t
{
crypto::hash prefix_hash;
crypto::key_image ki;
std::vector<public_key> stealth_addresses;
std::vector<public_key> amount_commitments; // div 8
std::vector<public_key> blinded_asset_ids; // div 8
std::vector<public_key> concealing_points; // div 8
std::vector<CLSAG_GGXXG_input_ref_t> ring;
crypto::public_key pseudo_output_commitment; // div 8
crypto::public_key pseudo_out_blinded_asset_id; // div 8
crypto::public_key extended_amount_commitment; // div 8
scalar_t secret_xp;
scalar_t secret_f; // = f - f' = amount_blinding_mask - pseudo_commitment_blinding_mask
scalar_t secret_t;
scalar_t secret_x;
scalar_t secret_q;
size_t secret_index;
CLSAG_GGXXG_signature sig;
clsag_ggxxg_sig_check_t()
{}
void rebuild_ring()
{
ring.clear();
ring.reserve(stealth_addresses.size());
for(size_t i = 0; i < stealth_addresses.size(); ++i)
ring.emplace_back(stealth_addresses[i], amount_commitments[i], blinded_asset_ids[i], concealing_points[i]);
}
clsag_ggxxg_sig_check_t& operator=(const clsag_ggxxg_sig_check_t& rhs)
{
prefix_hash = rhs.prefix_hash;
ki = rhs.ki;
stealth_addresses = rhs.stealth_addresses;
amount_commitments = rhs.amount_commitments;
blinded_asset_ids = rhs.blinded_asset_ids;
concealing_points = rhs.concealing_points;
rebuild_ring();
pseudo_output_commitment = rhs.pseudo_output_commitment;
pseudo_out_blinded_asset_id = rhs.pseudo_out_blinded_asset_id;
extended_amount_commitment = rhs.extended_amount_commitment;
secret_xp = rhs.secret_xp;
secret_f = rhs.secret_f;
secret_t = rhs.secret_t;
secret_x = rhs.secret_x;
secret_q = rhs.secret_q;
secret_index = rhs.secret_index;
return *this;
}
void prepare_random_data(size_t ring_size)
{
stealth_addresses.clear();
amount_commitments.clear();
blinded_asset_ids.clear();
concealing_points.clear();
ring.clear();
crypto::generate_random_bytes(sizeof prefix_hash, &prefix_hash);
stealth_addresses.reserve(ring_size);
amount_commitments.reserve(ring_size);
blinded_asset_ids.reserve(ring_size);
concealing_points.reserve(ring_size);
for(size_t i = 0; i < ring_size; ++i)
{
stealth_addresses.push_back(hash_helper_t::hp(scalar_t::random()).to_public_key());
amount_commitments.push_back(hash_helper_t::hp(scalar_t::random()).to_public_key()); // div 8
blinded_asset_ids.push_back(hash_helper_t::hp(scalar_t::random()).to_public_key()); // div 8
concealing_points.push_back(hash_helper_t::hp(scalar_t::random()).to_public_key()); // div 8
ring.emplace_back(stealth_addresses.back(), amount_commitments.back(), blinded_asset_ids.back(), concealing_points.back());
}
secret_xp = scalar_t::random();
secret_f = scalar_t::random();
secret_t = scalar_t::random();
secret_x = scalar_t::random();
secret_q = scalar_t::random();
secret_index = random_in_range(0, ring_size - 1);
stealth_addresses[secret_index] = (secret_xp * c_point_G).to_public_key();
concealing_points[secret_index] = (c_scalar_1div8 * secret_q * c_point_G).to_public_key();
ki = (secret_xp * hash_helper_t::hp(stealth_addresses[secret_index])).to_key_image();
pseudo_output_commitment = (point_t(amount_commitments[secret_index]) - c_scalar_1div8 * secret_f * c_point_G).to_public_key();
pseudo_out_blinded_asset_id = (point_t(blinded_asset_ids[secret_index]) - c_scalar_1div8 * secret_t * c_point_X).to_public_key();
extended_amount_commitment = (c_scalar_1div8 * secret_x * c_point_X + point_t(amount_commitments[secret_index]) + point_t(concealing_points[secret_index])).to_public_key();
}
bool generate()
{
try
{
return generate_CLSAG_GGXXG(prefix_hash, ring, point_t(pseudo_output_commitment).modify_mul8(), point_t(pseudo_out_blinded_asset_id).modify_mul8(), point_t(extended_amount_commitment).modify_mul8(), ki,
secret_xp, secret_f, secret_t, secret_x, secret_q, secret_index, sig);
}
catch(std::exception& e)
{
LOG_PRINT_RED(ENDL << "EXCEPTION: " << e.what(), LOG_LEVEL_0);
return false;
}
}
bool verify()
{
try
{
return verify_CLSAG_GGXXG(prefix_hash, ring, pseudo_output_commitment, pseudo_out_blinded_asset_id, extended_amount_commitment, ki, sig);
}
catch(std::exception& e)
{
LOG_PRINT_RED(ENDL << "EXCEPTION: " << e.what(), LOG_LEVEL_0);
return false;
}
}
};
TEST(clsag_ggxxg, basics)
{
std::string X_hash_str("X_generator");
point_t X = hash_helper_t::hp(X_hash_str.c_str(), X_hash_str.size());
LOG_PRINT_L0("X = " << X.to_hex_comma_separated_uint64_str());
ASSERT_EQ(X, c_point_X);
clsag_ggxxg_sig_check_t cc;
cc.prepare_random_data(1);
ASSERT_TRUE(cc.generate());
ASSERT_TRUE(cc.verify());
cc.prepare_random_data(2);
ASSERT_TRUE(cc.generate());
ASSERT_TRUE(cc.verify());
cc.prepare_random_data(8);
ASSERT_TRUE(cc.generate());
ASSERT_TRUE(cc.verify());
cc.prepare_random_data(123);
ASSERT_TRUE(cc.generate());
ASSERT_TRUE(cc.verify());
return true;
}