forked from lthn/blockchain
Zarcanum PoS validation: zarcanum_verify_proof, prevalidate_miner_transaction, BPPE changed from H2 to X, etc.
This commit is contained in:
parent
3aafd31992
commit
fd5ecfc64c
9 changed files with 70 additions and 26 deletions
|
|
@ -317,7 +317,7 @@ namespace crypto
|
|||
hsc.add_point(alpha_g * ki_base);
|
||||
hsc.add_point(alpha_x * c_point_X);
|
||||
hsc.add_point(alpha_x * ki_base);
|
||||
DBG_PRINT("c[" << secret_index << "] = Hs(ih, " << alpha_g * c_point_G << ", " << alpha_g * ki_base << ", " << alpha_x * c_point_X << ", " << alpha_x * ki_base << ")");
|
||||
//DBG_PRINT("c[" << secret_index << "] = Hs(ih, " << alpha_g * c_point_G << ", " << alpha_g * ki_base << ", " << alpha_x * c_point_X << ", " << alpha_x * ki_base << ")");
|
||||
scalar_t c_prev = hsc.calc_hash(); // c_{secret_index + 1}
|
||||
|
||||
sig.r_g.clear();
|
||||
|
|
@ -355,8 +355,8 @@ namespace crypto
|
|||
}
|
||||
|
||||
|
||||
bool verify_CLSAG_GGXG(const hash& m, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const public_key& pseudo_out_amount_commitment, const public_key& extended_amount_commitment, const key_image& ki,
|
||||
const CLSAG_GGXG_signature& sig)
|
||||
bool verify_CLSAG_GGXG(const hash& m, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const public_key& pseudo_out_amount_commitment, const public_key& extended_amount_commitment,
|
||||
const key_image& ki, const CLSAG_GGXG_signature& sig)
|
||||
{
|
||||
DBG_PRINT("== verify_CLSAG_GGXG ==");
|
||||
size_t ring_size = ring.size();
|
||||
|
|
@ -474,7 +474,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;
|
||||
|
|
|
|||
|
|
@ -32,15 +32,18 @@ namespace crypto
|
|||
struct CLSAG_GG_input_ref_t
|
||||
{
|
||||
CLSAG_GG_input_ref_t(const public_key& stealth_address, const public_key& amount_commitment)
|
||||
: stealth_address(stealth_address), amount_commitment(amount_commitment) {}
|
||||
: stealth_address(stealth_address), amount_commitment(amount_commitment)
|
||||
{}
|
||||
|
||||
const public_key& stealth_address; // not premultiplied by 1/8, TODO @#@#: make sure it's okay
|
||||
const public_key& amount_commitment; // multiplied by 1/8
|
||||
const public_key& stealth_address; // P, not premultiplied by 1/8, TODO @#@#: make sure it's okay
|
||||
const public_key& amount_commitment; // A, premultiplied by 1/8
|
||||
};
|
||||
|
||||
// pseudo_out_amount_commitment -- not premultiplied by 1/8
|
||||
bool generate_CLSAG_GG(const hash& m, const std::vector<CLSAG_GG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment, const key_image& ki,
|
||||
const scalar_t& secret_x, const scalar_t& secret_f, uint64_t secret_index, CLSAG_GG_signature& sig);
|
||||
|
||||
// pseudo_out_amount_commitment -- premultiplied by 1/8
|
||||
bool verify_CLSAG_GG(const hash& m, const std::vector<CLSAG_GG_input_ref_t>& ring, const public_key& pseudo_out_amount_commitment, const key_image& ki,
|
||||
const CLSAG_GG_signature& sig);
|
||||
|
||||
|
|
@ -71,10 +74,15 @@ namespace crypto
|
|||
const public_key& concealing_point; // Q, premultiplied by 1/8
|
||||
};
|
||||
|
||||
// pseudo_out_amount_commitment -- not premultiplied by 1/8
|
||||
// extended_amount_commitment -- not premultiplied by 1/8
|
||||
bool generate_CLSAG_GGXG(const hash& m, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment, const point_t& extended_amount_commitment, const key_image& ki,
|
||||
const scalar_t& secret_0_xp, const scalar_t& secret_1_f, const scalar_t& secret_2_x, const scalar_t& secret_3_q, uint64_t secret_index, CLSAG_GGXG_signature& sig);
|
||||
|
||||
bool verify_CLSAG_GGXG(const hash& m, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const public_key& pseudo_out_amount_commitment, const public_key& extended_amount_commitment, const key_image& ki,
|
||||
const CLSAG_GGXG_signature& sig);
|
||||
// pseudo_out_amount_commitment -- premultiplied by 1/8
|
||||
// extended_amount_commitment -- premultiplied by 1/8
|
||||
// may throw an exception TODO @#@# make sure it's okay
|
||||
bool verify_CLSAG_GGXG(const hash& m, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const public_key& pseudo_out_amount_commitment,
|
||||
const public_key& extended_amount_commitment, const key_image& ki, const CLSAG_GGXG_signature& sig);
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ namespace crypto
|
|||
const point_t& bpp_crypto_trait_zano<N, values_max>::bpp_H = c_point_G;
|
||||
|
||||
template<size_t N, size_t values_max>
|
||||
const point_t& bpp_crypto_trait_zano<N, values_max>::bpp_H2 = c_point_H2;
|
||||
const point_t& bpp_crypto_trait_zano<N, values_max>::bpp_H2 = c_point_X;
|
||||
|
||||
|
||||
// efficient multiexponentiation (naive stub implementation atm, TODO)
|
||||
|
|
|
|||
|
|
@ -45,9 +45,8 @@ namespace crypto
|
|||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("zarcanum_generate_proof: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<crypto::CLSAG_GGXG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment,
|
||||
bool zarcanum_generate_proof(const hash& m, const hash& kernel_hash, const std::vector<CLSAG_GGXG_input_ref_t>& ring, const point_t& pseudo_out_amount_commitment,
|
||||
const scalar_t& last_pow_block_id_hashed, const key_image& stake_ki,
|
||||
const scalar_t& secret_x, const scalar_t& secret_q, uint64_t secret_index, const scalar_t& pseudo_out_blinding_mask, uint64_t stake_amount, const scalar_t& stake_blinding_mask,
|
||||
zarcanum_proof& result, uint8_t* p_err /* = nullptr */)
|
||||
|
|
@ -117,7 +116,7 @@ namespace crypto
|
|||
const scalar_vec_t masks2 = { bx }; // X component
|
||||
const std::vector<const public_key*> E_1div8_vec_ptr = { &result.E };
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks2, E_1div8_vec_ptr, result.E_range_proof), 10);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bppe_gen<bpp_crypto_trait_zano<128>>(values, masks, masks2, E_1div8_vec_ptr, result.E_range_proof), 10);
|
||||
|
||||
// = four-layers ring signature data outline =
|
||||
// (j in [0, ring_size-1])
|
||||
|
|
@ -144,6 +143,9 @@ namespace crypto
|
|||
// Q[j]
|
||||
// layer 3 secret (with respect to G)
|
||||
// secret_q
|
||||
|
||||
result.pseudo_out_amount_commitment = (crypto::c_scalar_1div8 * pseudo_out_amount_commitment).to_public_key();
|
||||
|
||||
TRY_ENTRY()
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(generate_CLSAG_GGXG(m, ring, pseudo_out_amount_commitment, C, stake_ki,
|
||||
secret_x, stake_blinding_mask - pseudo_out_blinding_mask, x0, secret_q, secret_index,
|
||||
|
|
@ -152,11 +154,27 @@ namespace crypto
|
|||
|
||||
return true;
|
||||
}
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
|
||||
|
||||
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err /* = nullptr */)
|
||||
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("zarcanum_verify_proof: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
bool zarcanum_verify_proof(const hash& m, const hash& kernel_hash, const std::vector<CLSAG_GGXG_input_ref_t>& ring,
|
||||
const scalar_t& last_pow_block_id_hashed, const key_image& stake_ki,
|
||||
const zarcanum_proof& sig, uint8_t* p_err /* = nullptr */)
|
||||
{
|
||||
return false;
|
||||
bool r = false;
|
||||
|
||||
std::vector<point_t> E_for_range_proof = { point_t(sig.E) };
|
||||
std::vector<bppe_sig_commit_ref_t> range_proofs = { bppe_sig_commit_ref_t(sig.E_range_proof, E_for_range_proof) };
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bppe_verify<bpp_crypto_trait_zano<128>>(range_proofs), 10);
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(verify_CLSAG_GGXG(m, ring, sig.pseudo_out_amount_commitment, sig.C, stake_ki, sig.clsag_ggxg), 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ namespace crypto
|
|||
zarcanum_proof& result, uint8_t* p_err = nullptr);
|
||||
|
||||
|
||||
bool zarcanum_verify_proof(const hash& kernel_hash, const public_key& commitment_1div8, const scalar_t& last_pow_block_id_hashed, const zarcanum_proof& proof, uint8_t* p_err = nullptr);
|
||||
bool zarcanum_verify_proof(const hash& m, const hash& kernel_hash, const std::vector<crypto::CLSAG_GGXG_input_ref_t>& ring,
|
||||
const scalar_t& last_pow_block_id_hashed, const key_image& stake_ki,
|
||||
const zarcanum_proof& sig, uint8_t* p_err = nullptr);
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "tx_semantic_validation.h"
|
||||
#include "crypto/RIPEMD160_helper.h"
|
||||
#include "crypto/bitcoin/sha256_helper.h"
|
||||
#include "crypto_config.h"
|
||||
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
|
|
@ -1280,7 +1281,10 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t
|
|||
}
|
||||
if (pos)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_to_key), false, "coinstake transaction in the block has the wrong type");
|
||||
if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_zc_input), false, "coinstake tx has incorrect type of input #1: " << b.miner_tx.vin[1].type().name());
|
||||
else
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.vin[1].type() == typeid(txin_to_key), false, "coinstake tx has incorrect type of input #1: " << b.miner_tx.vin[1].type().name());
|
||||
}
|
||||
|
||||
if (m_core_runtime_config.is_hardfork_active_for_height(1, height))
|
||||
|
|
@ -1315,11 +1319,19 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t
|
|||
return false;
|
||||
}
|
||||
|
||||
if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM))
|
||||
if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment.size() == 2, false, "coinbase transaction has incorrect number of attachments (" << b.miner_tx.attachment.size() << "), expected 2");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment[0].type() == typeid(zc_outs_range_proof), false, "coinbase transaction wrong attachment #0 type (expected: zc_outs_range_proof)");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment[1].type() == typeid(zc_balance_proof), false, "coinbase transaction wrong attachmenttype #1 (expected: zc_balance_proof)");
|
||||
if (pos)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment.size() == 1, false, "coinbase transaction has incorrect number of attachments (" << b.miner_tx.attachment.size() << "), expected 2");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment[0].type() == typeid(zc_outs_range_proof), false, "coinbase transaction wrong attachment #0 type (expected: zc_outs_range_proof)");
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment.size() == 2, false, "coinbase transaction has incorrect number of attachments (" << b.miner_tx.attachment.size() << "), expected 2");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment[0].type() == typeid(zc_outs_range_proof), false, "coinbase transaction wrong attachment #0 type (expected: zc_outs_range_proof)");
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.attachment[1].type() == typeid(zc_balance_proof), false, "coinbase transaction wrong attachmenttype #1 (expected: zc_balance_proof)");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5441,10 +5453,13 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
for(auto& zc_out : scan_contex.zc_outs)
|
||||
ring.emplace_back(zc_out.stealth_address, zc_out.amount_commitment, zc_out.concealing_point);
|
||||
|
||||
r = crypto::verify_CLSAG_GGXG(miner_tx_hash, ring, sig.pseudo_out_amount_commitment, sig.C, stake_input.k_image, sig.clsag_ggxg);
|
||||
CHECK_AND_ASSERT_MES(r, false, "verify_CLSAG_GGXG failed");
|
||||
crypto::scalar_t last_pow_block_id_hashed = crypto::hash_helper_t::hs(CRYPTO_HDS_ZARCANUM_LAST_POW_HASH, sm.last_pow_id);
|
||||
|
||||
uint8_t err = 0;
|
||||
r = crypto::zarcanum_verify_proof(miner_tx_hash, kernel_hash, ring, last_pow_block_id_hashed, stake_input.k_image, sig, &err);
|
||||
CHECK_AND_ASSERT_MES(r, false, "zarcanum_verify_proof failed with code " << err);
|
||||
|
||||
return false; // not implemented yet, TODO @#@#
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#define CRYPTO_HDS_CLSAG_GGXG_CHALLENGE "ZANO_HDS_CLSAG_GGXG_CHALLENGE__"
|
||||
|
||||
#define CRYPTO_HDS_ZARCANUM_LAST_POW_HASH "ZANO_HDS_ZARCANUM_LAST_POW_HASH"
|
||||
#define CRYPTO_HDS_ZARCANUM_SECRET_Q "ZANO_HDS_ZARCANUM_SECRET_Q_____"
|
||||
#define CRYPTO_HDS_ZARCANUM_PROOF_HASH "ZANO_HDS_ZARCANUM_PROOF_HASH___"
|
||||
|
||||
#define CRYPTO_HDS_ASSET_CONTROL_KEY "ZANO_HDS_ASSET_CONTROL_KEY_____"
|
||||
|
|
|
|||
|
|
@ -387,6 +387,9 @@ namespace currency
|
|||
VARIANT_CASE_CONST(ZC_sig, zc_sig);
|
||||
sum_of_pseudo_out_amount_commitments += crypto::point_t(zc_sig.pseudo_out_amount_commitment); // *1/8
|
||||
++zc_sigs_count;
|
||||
VARIANT_CASE_CONST(zarcanum_sig, sig);
|
||||
sum_of_pseudo_out_amount_commitments += crypto::point_t(sig.pseudo_out_amount_commitment); // *1/8
|
||||
++zc_sigs_count;
|
||||
VARIANT_SWITCH_END();
|
||||
}
|
||||
sum_of_pseudo_out_amount_commitments.modify_mul8();
|
||||
|
|
|
|||
|
|
@ -3796,7 +3796,6 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl
|
|||
|
||||
crypto::scalar_t pseudo_out_blinding_mask = crypto::scalar_t::random();
|
||||
crypto::point_t pseudo_out_amount_commitment = td.m_amount * crypto::c_point_H + pseudo_out_blinding_mask * crypto::c_point_G;
|
||||
sig.pseudo_out_amount_commitment = (crypto::c_scalar_1div8 * pseudo_out_amount_commitment).to_public_key();
|
||||
|
||||
crypto::hash tx_hash_for_sig = get_transaction_hash(b.miner_tx);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue