interim checkin
This commit is contained in:
@@ -423,7 +423,7 @@ namespace boost
|
||||
a & x.p_r;
|
||||
if (x.type == rct::RCTTypeFullProofs) {
|
||||
a & x.pr_proof;
|
||||
//a & x.sa_proofs;
|
||||
a & x.sa_proofs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace boost
|
||||
a & x.p_r;
|
||||
if (x.type == rct::RCTTypeFullProofs) {
|
||||
a & x.pr_proof;
|
||||
//a & x.sa_proofs;
|
||||
a & x.sa_proofs;
|
||||
}
|
||||
//--------------
|
||||
a & x.p.rangeSigs;
|
||||
|
||||
@@ -3619,10 +3619,12 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
||||
}
|
||||
|
||||
if (hf_version >= HF_VERSION_FULL_PROOFS) {
|
||||
if (tx.rct_signatures.type != rct::RCTTypeFullProofs) {
|
||||
MERROR_VER("FullProofs required after v" + std::to_string(HF_VERSION_FULL_PROOFS));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
if (tx.type == cryptonote::transaction_type::TRANSFER) {
|
||||
if (tx.rct_signatures.type != rct::RCTTypeFullProofs) {
|
||||
MERROR_VER("FullProofs required for TRANSFER TXs after v" + std::to_string(HF_VERSION_FULL_PROOFS));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -858,6 +858,7 @@ namespace cryptonote
|
||||
//fill outputs
|
||||
size_t output_index = 0;
|
||||
crypto::secret_key x_change = crypto::null_skey;
|
||||
rct::key key_yF;
|
||||
uint8_t change_index = 0;
|
||||
for(const tx_destination_entry& dst_entr: destinations)
|
||||
{
|
||||
@@ -970,6 +971,12 @@ namespace cryptonote
|
||||
// Push the F point into the TX vector of F points
|
||||
tx.return_address_list.push_back(F);
|
||||
|
||||
// Calculate the shared secret yF
|
||||
if (hf_version >= HF_VERSION_FULL_PROOFS) {
|
||||
rct::key key_aP = rct::scalarmultKey(rct::pk2rct(P_change), rct::sk2rct(sender_account_keys.m_view_secret_key));
|
||||
key_yF = rct::hash_to_scalar(key_aP);
|
||||
}
|
||||
|
||||
// Calculate the encrypted_change_index data for this output
|
||||
struct {
|
||||
char domain_separator[8];
|
||||
@@ -1209,7 +1216,8 @@ namespace cryptonote
|
||||
rct_config,
|
||||
hwdev,
|
||||
rct::sk2rct(x_change),
|
||||
change_index
|
||||
change_index,
|
||||
key_yF
|
||||
);
|
||||
else
|
||||
tx.rct_signatures = rct::genRct(rct::hash2rct(tx_prefix_hash), inSk, destinations, outamounts, mixRing, amount_keys, sources[0].real_output, outSk, rct_config, hwdev); // same index assumption
|
||||
|
||||
@@ -1098,7 +1098,7 @@ namespace rct {
|
||||
return index;
|
||||
}
|
||||
|
||||
std::vector<zk_proof> SAProof_Gen(const keyV &pubkeys, const key &x_change, const size_t change_index) {
|
||||
std::vector<zk_proof> SAProof_Gen(const keyV &pubkeys, const key &x_change, const size_t change_index, const key &key_yF) {
|
||||
|
||||
// Declare a return structure
|
||||
std::vector<zk_proof> proofs{};
|
||||
@@ -1126,9 +1126,10 @@ namespace rct {
|
||||
|
||||
// Calculate the challenge hash from the commitments plus the pubkeys
|
||||
keyV challenge_keys;
|
||||
challenge_keys.reserve(pubkeys.size() * 2);
|
||||
challenge_keys.reserve(pubkeys.size() * 2 + 1);
|
||||
challenge_keys.insert(challenge_keys.end(), commitments.begin(), commitments.end());
|
||||
challenge_keys.insert(challenge_keys.end(), pubkeys.begin(), pubkeys.end());
|
||||
challenge_keys.push_back(key_yF);
|
||||
rct::key c = rct::hash_to_scalar(challenge_keys);
|
||||
sc_reduce32(c.bytes);
|
||||
|
||||
@@ -1144,8 +1145,8 @@ namespace rct {
|
||||
rct::key z_x;
|
||||
sc_muladd(z_x.bytes, x_val.bytes, c.bytes, scalars[j].bytes);
|
||||
//rct::key z_x = rct::addKeys(scalars[j], rct::scalarmultKey(c, x_val));
|
||||
rct::key z_y = scalars[j];
|
||||
proofs.push_back({commitments[j], z_x, z_y});
|
||||
//rct::key z_y = scalars[j];
|
||||
proofs.push_back({commitments[j], z_x, rct::zero()});
|
||||
}
|
||||
|
||||
// Return the proof to the caller
|
||||
@@ -1153,18 +1154,19 @@ namespace rct {
|
||||
}
|
||||
|
||||
|
||||
bool SAProof_Ver(const std::vector<zk_proof> &proofs, const keyV &pubkeys, const size_t change_index) {
|
||||
bool SAProof_Ver(const std::vector<zk_proof> &proofs, const keyV &pubkeys, const size_t change_index, const key &key_yF) {
|
||||
// Sanity checks
|
||||
CHECK_AND_ASSERT_THROW_MES(proofs.size() == pubkeys.size(), "PRProof_Ver() failed - proof count does not match output count");
|
||||
CHECK_AND_ASSERT_THROW_MES(change_index < pubkeys.size(), "PRProof_Ver() failed - invalid change index provided");
|
||||
|
||||
// Recompute the challenge hash
|
||||
keyV challenge_keys;
|
||||
challenge_keys.reserve(pubkeys.size() * 2);
|
||||
challenge_keys.reserve(pubkeys.size() * 2 + 1);
|
||||
for (const auto &proof_entr: proofs) {
|
||||
challenge_keys.push_back(proof_entr.R);
|
||||
}
|
||||
challenge_keys.insert(challenge_keys.end(), pubkeys.begin(), pubkeys.end());
|
||||
challenge_keys.push_back(key_yF);
|
||||
rct::key c = rct::hash_to_scalar(challenge_keys);
|
||||
sc_reduce32(c.bytes);
|
||||
|
||||
@@ -1172,23 +1174,17 @@ namespace rct {
|
||||
const auto &proof = proofs[change_index];
|
||||
const rct::key &R = proof.R; // Commitment
|
||||
const rct::key &z_x = proof.z1; // z_x value
|
||||
const rct::key &z_y = proof.z2; // z_y value
|
||||
const rct::key P = pubkeys[change_index];
|
||||
|
||||
// Verify the proof for the change output
|
||||
// Recalculate the expected commitment using the formula: z_x * G = R + c * P
|
||||
rct::key expected_commitment = rct::addKeys(R, rct::scalarmultKey(c, P));
|
||||
rct::key expected_commitment = rct::addKeys(R, rct::scalarmultKey(P, c));
|
||||
|
||||
// Verify z_x * G matches the expected commitment
|
||||
if (!rct::equalKeys(rct::scalarmultBase(z_x), expected_commitment)) {
|
||||
return false; // Verification failed
|
||||
}
|
||||
|
||||
// Verify z_y * G matches the original commitment
|
||||
if (!rct::equalKeys(rct::scalarmultBase(z_y), R)) {
|
||||
return false; // Verification failed
|
||||
}
|
||||
|
||||
// All checks passed
|
||||
return true;
|
||||
}
|
||||
@@ -1281,7 +1277,8 @@ namespace rct {
|
||||
const RCTConfig &rct_config,
|
||||
hw::device &hwdev,
|
||||
const key &x_change,
|
||||
const size_t change_index
|
||||
const size_t change_index,
|
||||
const key &key_yF
|
||||
)
|
||||
{
|
||||
const bool bulletproof_or_plus = rct_config.range_proof_type > RangeProofBorromean;
|
||||
@@ -1451,6 +1448,16 @@ namespace rct {
|
||||
DP(rv.p_r);
|
||||
if (rv.type == RCTTypeFullProofs)
|
||||
rv.pr_proof = PRProof_Gen(difference);
|
||||
|
||||
// Check if spend authority proof is needed (only for TRANSFER TXs)
|
||||
rv.sa_proofs.clear();
|
||||
if (tx_type == cryptonote::transaction_type::TRANSFER && rv.type == rct::RCTTypeFullProofs) {
|
||||
rv.sa_proofs = SAProof_Gen(destinations, x_change, change_index, key_yF);
|
||||
//#ifdef DBG
|
||||
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.sa_proofs, destinations, change_index, key_yF), "SAProof_Ver() failed on recently created proof");
|
||||
//#endif
|
||||
}
|
||||
|
||||
key full_message = get_pre_mlsag_hash(rv,hwdev);
|
||||
|
||||
for (i = 0 ; i < inamounts.size(); i++)
|
||||
@@ -1468,16 +1475,6 @@ namespace rct {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if spend authority proof is needed (only for TRANSFER TXs)
|
||||
/*
|
||||
if (tx_type == cryptonote::transaction_type::TRANSFER && rv.type == rct::RCTTypeFullProofs) {
|
||||
rv.sa_proofs = SAProof_Gen(destinations, x_change, change_index);
|
||||
#ifdef DBG
|
||||
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.sa_proofs, destinations, change_index), "SAProof_Ver() failed on recently created proof");
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1497,7 +1494,8 @@ namespace rct {
|
||||
const RCTConfig &rct_config,
|
||||
hw::device &hwdev,
|
||||
const key &x_change,
|
||||
const size_t change_index
|
||||
const size_t change_index,
|
||||
const key &key_yF
|
||||
) {
|
||||
std::vector<unsigned int> index;
|
||||
index.resize(inPk.size());
|
||||
@@ -1508,7 +1506,7 @@ namespace rct {
|
||||
mixRing[i].resize(mixin+1);
|
||||
index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin);
|
||||
}
|
||||
return genRctSimple(message, inSk, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev, x_change, change_index);
|
||||
return genRctSimple(message, inSk, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev, x_change, change_index, key_yF);
|
||||
}
|
||||
|
||||
//RingCT protocol
|
||||
|
||||
@@ -88,8 +88,8 @@ namespace rct {
|
||||
zk_proof PRProof_Gen(const rct::key &difference);
|
||||
bool PRProof_Ver(const rct::key &C, const zk_proof &proof);
|
||||
|
||||
std::vector<zk_proof> SAProof_Gen(const keyV &pubkeys, const key &x_change, const size_t change_index);
|
||||
bool SAProof_Ver(const std::vector<zk_proof> &proofs, const keyV &pubkeys, const size_t change_index);
|
||||
std::vector<zk_proof> SAProof_Gen(const keyV &pubkeys, const key &x_change, const size_t change_index, const key &key_yF);
|
||||
bool SAProof_Ver(const std::vector<zk_proof> &proofs, const keyV &pubkeys, const size_t change_index, const key &key_yF);
|
||||
|
||||
//proveRange and verRange
|
||||
//proveRange gives C, and mask such that \sumCi = C
|
||||
@@ -150,7 +150,8 @@ namespace rct {
|
||||
const RCTConfig &rct_config,
|
||||
hw::device &hwdev,
|
||||
const key &x_change = rct::zero(),
|
||||
const size_t change_index = 0
|
||||
const size_t change_index = 0,
|
||||
const key &key_yF = rct::zero()
|
||||
);
|
||||
rctSig genRctSimple(
|
||||
const key & message,
|
||||
@@ -169,7 +170,8 @@ namespace rct {
|
||||
const RCTConfig &rct_config,
|
||||
hw::device &hwdev,
|
||||
const key &x_change = rct::zero(),
|
||||
const size_t change_index = 0
|
||||
const size_t change_index = 0,
|
||||
const key &key_yF = rct::zero()
|
||||
);
|
||||
bool verRct(const rctSig & rv, bool semantics);
|
||||
static inline bool verRct(const rctSig & rv) { return verRct(rv, true) && verRct(rv, false); }
|
||||
|
||||
@@ -421,6 +421,7 @@ namespace rct {
|
||||
if (type == RCTTypeFullProofs)
|
||||
{
|
||||
FIELD(pr_proof)
|
||||
FIELD(sa_proofs)
|
||||
/*
|
||||
uint32_t nsap = sa_proofs.size();
|
||||
VARINT_FIELD(nsap)
|
||||
@@ -452,7 +453,7 @@ namespace rct {
|
||||
FIELD(p_r)
|
||||
if (type == RCTTypeFullProofs) {
|
||||
FIELD(pr_proof)
|
||||
//FIELD(sa_proofs)
|
||||
FIELD(sa_proofs)
|
||||
}
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user