updated SA_Proof functions to use domain separator hash key

This commit is contained in:
Some Random Crypto Guy
2025-06-05 13:40:29 +01:00
parent d163d6892c
commit ec2015e5a4
6 changed files with 24 additions and 14 deletions

View File

@@ -160,8 +160,8 @@ void get_output_enote_proposals(const std::vector<CarrotPaymentProposalV1> &norm
const crypto::key_image &tx_first_key_image,
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
encrypted_payment_id_t &encrypted_payment_id_out,
size_t change_index_out,
std::vector<std::pair<bool, std::size_t>> *payment_proposal_order_out)
std::vector<std::pair<bool, std::size_t>> *payment_proposal_order_out,
size_t change_index_out)
{
output_enote_proposals_out.clear();
encrypted_payment_id_out = {{0}};

View File

@@ -110,8 +110,8 @@ void get_output_enote_proposals(const std::vector<CarrotPaymentProposalV1> &norm
const crypto::key_image &tx_first_key_image,
std::vector<RCTOutputEnoteProposal> &output_enote_proposals_out,
encrypted_payment_id_t &encrypted_payment_id_out,
size_t change_index_out = 0,
std::vector<std::pair<bool, std::size_t>> *payment_proposal_order_out = nullptr);
std::vector<std::pair<bool, std::size_t>> *payment_proposal_order_out = nullptr,
size_t change_index_out = 0);
/**
* brief: get_coinbase_output_enotes - convert a *finalized* set of payment proposals into coinbase output enotes
* param: normal_payment_proposals -

View File

@@ -359,6 +359,7 @@ namespace config
const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS_SEED[] = "multisig_tx_privkeys_seed";
const constexpr char HASH_KEY_MULTISIG_TX_PRIVKEYS[] = "multisig_tx_privkeys";
const constexpr char HASH_KEY_TXHASH_AND_MIXRING[] = "txhash_and_mixring";
const constexpr char HASH_KEY_SA_PROOF[] = "SPARC_sa_proof_domain_separator";
// Multisig
const uint32_t MULTISIG_MAX_SIGNERS{16};

View File

@@ -1374,13 +1374,12 @@ namespace rct {
return index;
}
zk_proof SAProof_Gen(const key &P, const key &x_change, const key &y_change, const key &key_yF) {
zk_proof SAProof_Gen(const key &P, const key &x_change, const key &y_change) {
// Sanity checks for inputs
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(P, rct::zero()), "SAProof_Gen() failed - invalid public key provided");
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(x_change, rct::zero()), "SAProof_Gen() failed - invalid x_change key provided");
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(y_change, rct::zero()), "SAProof_Gen() failed - invalid y_change key provided");
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(key_yF, rct::zero()), "SAProof_Gen() failed - invalid shared secret key provided");
// Declare a return structure
zk_proof proof{};
@@ -1389,9 +1388,14 @@ namespace rct {
rct::key r_x = rct::skGen();
rct::key r_y = rct::skGen();
rct::addKeys2(proof.R, r_x, r_y, rct::pk2rct(crypto::get_T()));
// Make the domain separator into a key
rct::key sa_proof_domain_sep;
sc_0(sa_proof_domain_sep.bytes);
memcpy(sa_proof_domain_sep.bytes,config::HASH_KEY_SA_PROOF,sizeof(config::HASH_KEY_SA_PROOF)-1);
// Calculate the challenge hash from the commitment plus the pubkey plus the shared secret
keyV challenge_keys{proof.R, P, key_yF};
keyV challenge_keys{sa_proof_domain_sep, proof.R, P};
rct::key c = rct::hash_to_scalar(challenge_keys);
rct::key z_x,z_y;
@@ -1404,14 +1408,18 @@ namespace rct {
return proof;
}
bool SAProof_Ver(const zk_proof &proof, const key &P, const key &key_yF) {
bool SAProof_Ver(const zk_proof &proof, const key &P) {
// Sanity checks for inputs
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(P, rct::zero()), "SAProof_Ver() failed - invalid public key provided");
CHECK_AND_ASSERT_THROW_MES(!rct::equalKeys(key_yF, rct::zero()), "SAProof_Ver() failed - invalid shared secret key provided");
// Make the domain separator into a key
rct::key sa_proof_domain_sep;
sc_0(sa_proof_domain_sep.bytes);
memcpy(sa_proof_domain_sep.bytes,config::HASH_KEY_SA_PROOF,sizeof(config::HASH_KEY_SA_PROOF)-1);
// Recompute the challenge hash
keyV challenge_keys{proof.R, P, key_yF};
keyV challenge_keys{sa_proof_domain_sep, proof.R, P};
rct::key c = rct::hash_to_scalar(challenge_keys);
// Recalculate the expected commitment using the formula: R + c * P
@@ -1511,7 +1519,7 @@ namespace rct {
xmr_amount txnFee,
const ctkeyM & mixRing,
const std::vector<unsigned int> & index,
ctkeyV &outSk,
const ctkeyV &outSk,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,
@@ -1592,9 +1600,9 @@ namespace rct {
// Check if spend authority proof is needed (only for TRANSFER TXs)
if (tx_type == cryptonote::transaction_type::TRANSFER && rv.type == rct::RCTTypeSalviumOne) {
rv.salvium_data.sa_proof = SAProof_Gen(destinations[change_index], x_change, y_change, key_yF);
rv.salvium_data.sa_proof = SAProof_Gen(destinations[change_index], x_change, y_change);
#ifdef DBG
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.salvium_data.sa_proof, destinations[change_index], key_yF), "SAProof_Ver() failed on recently created proof");
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.salvium_data.sa_proof, destinations[change_index]), "SAProof_Ver() failed on recently created proof");
#endif
}

View File

@@ -150,7 +150,7 @@ namespace rct {
xmr_amount txnFee,
const ctkeyM & mixRing,
const std::vector<unsigned int> & index,
ctkeyV &outSk,
const ctkeyV &outSk,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,

View File

@@ -769,6 +769,7 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
tx_proposal.key_images_sorted.at(0),
output_enote_proposals,
encrypted_payment_id,
nullptr,
change_index);
CHECK_AND_ASSERT_THROW_MES(output_enote_proposals.size() == n_outputs,
"finalize_all_proofs_from_transfer_details: unexpected number of output enote proposals");