Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

seraphis_knowledge_proofs: Enote Amount Proof w/o revealing blinding … #14

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/seraphis_main/sp_knowledge_proof_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,17 @@ struct EnoteOwnershipProofV1

////
// EnoteAmountProofV1
// - proof an enote with amount commitment C has a particular amount a
// - proof an enote with amount commitment C has a particular amount a (w/o revealing blinding factor)
//
// - VERIFIER: recompute C ?= x G + a H
// - VERIFIER:
// - compute C0 = C - aH
// - verify proof of knowledge of discrete log of C0 against G
///
struct EnoteAmountProofV1
{
rct::xmr_amount a;
rct::key x;
rct::key C;
crypto::signature C0_sig;
};

////
Expand Down
38 changes: 28 additions & 10 deletions src/seraphis_main/sp_knowledge_proof_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,24 +460,39 @@ void make_enote_amount_proof_v1(const rct::xmr_amount &amount,
const rct::key &commitment,
EnoteAmountProofV1 &proof_out)
{
// C0 = C - aH
rct::key C0 = rct::scalarmultH(rct::d2h(amount));
rct::subKeys(C0, commitment, C0);

// Generate zero-knowlege proof of knowledge of discrete log of C0 w/ respect to G
crypto::signature C0_sig;
crypto::generate_signature(crypto::null_hash, rct::rct2pk(C0), mask, C0_sig);

proof_out = EnoteAmountProofV1{
.a = amount,
.x = rct::sk2rct(mask),
.C = commitment
.C = commitment,
.C0_sig = C0_sig
};
}
//-------------------------------------------------------------------------------------------------------------------
bool verify_enote_amount_proof_v1(const EnoteAmountProofV1 &proof, const rct::key &expected_commitment)
bool verify_enote_amount_proof_v1(const EnoteAmountProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_commitment)
{
// 1. check the proof matches the expected amount commitment
// 1. check the proof matches the expected amount
if (!(proof.a == expected_amount))
return false;

// 2. check the proof matches the expected amount commitment
if (!(proof.C == expected_commitment))
return false;

// 2. check the commitment can be reproduced
if (!(proof.C == rct::commit(proof.a, proof.x)))
return false;;
// C0 = C - aH
rct::key C0 = rct::scalarmultH(rct::d2h(proof.a));
rct::subKeys(C0, proof.C, C0);

return true;
// 3. check proof of knowledge of discrete log of C0 against G
return crypto::check_signature(crypto::null_hash, rct::rct2pk(C0), proof.C0_sig);
}
//-------------------------------------------------------------------------------------------------------------------
void make_enote_key_image_proof_v1(const rct::key &onetime_address,
Expand Down Expand Up @@ -736,6 +751,7 @@ void make_enote_sent_proof_v1(const EnoteOwnershipProofV1 &ownership_proof,
}
//-------------------------------------------------------------------------------------------------------------------
bool verify_enote_sent_proof_v1(const EnoteSentProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_amount_commitment,
const rct::key &expected_onetime_address)
{
Expand All @@ -746,7 +762,7 @@ bool verify_enote_sent_proof_v1(const EnoteSentProofV1 &proof,
return false;

// 2. verify the amount proof
if (!verify_enote_amount_proof_v1(proof.amount_proof, expected_amount_commitment))
if (!verify_enote_amount_proof_v1(proof.amount_proof, expected_amount, expected_amount_commitment))
return false;

return true;
Expand Down Expand Up @@ -802,6 +818,7 @@ void make_reserved_enote_proof_v1(const SpContextualEnoteRecordV1 &contextual_re
}
//-------------------------------------------------------------------------------------------------------------------
bool verify_reserved_enote_proof_v1(const ReservedEnoteProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_amount_commitment,
const rct::key &expected_onetime_address,
const std::uint64_t expected_enote_ledger_index)
Expand All @@ -813,7 +830,7 @@ bool verify_reserved_enote_proof_v1(const ReservedEnoteProofV1 &proof,
return false;

// 2. verify the enote amount proof
if (!verify_enote_amount_proof_v1(proof.amount_proof, expected_amount_commitment))
if (!verify_enote_amount_proof_v1(proof.amount_proof, expected_amount, expected_amount_commitment))
return false;

// 3. verify the key image proof
Expand Down Expand Up @@ -955,6 +972,7 @@ bool verify_reserve_proof_v1(const ReserveProofV1 &proof,
// c. validate the reserved enote proofs
// - we don't check expected values because all we care about is validity (we already checked address consistency)
if (!verify_reserved_enote_proof_v1(reserved_enote_proof,
reserved_enote_proof.amount_proof.a,
reserved_enote_proof.enote_ownership_proof.C,
reserved_enote_proof.enote_ownership_proof.Ko,
reserved_enote_proof.enote_ledger_index))
Expand Down
9 changes: 8 additions & 1 deletion src/seraphis_main/sp_knowledge_proof_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,13 @@ void make_enote_amount_proof_v1(const rct::xmr_amount &amount,
/**
* brief: verify enote amount proof
* param: proof - proof to verify
* param: expected_amount - amount expected to be in the proof
* param: expected_commitment - commitment expected to be in the proof
* return: true/false according to proof validity
*/
bool verify_enote_amount_proof_v1(const EnoteAmountProofV1 &proof, const rct::key &expected_commitment);
bool verify_enote_amount_proof_v1(const EnoteAmountProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_commitment);
/**
* brief: make an enote key image proof
* param: onetime_address - address which has the format xG + yX + zU.
Expand Down Expand Up @@ -251,11 +254,13 @@ void make_enote_sent_proof_v1(const EnoteOwnershipProofV1 &ownership_proof,
/**
* brief: verify enote sent proof
* param: proof - proof to verify
* param: expected_amount - expected amount of the proof enote
* param: expected_amount_commitment - expected amount commitment of the proof enote
* param: expected_onetime_address - expected onetime address of the proof enote
* return: true/false according to proof validity
*/
bool verify_enote_sent_proof_v1(const EnoteSentProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_amount_commitment,
const rct::key &expected_onetime_address);
/**
Expand All @@ -279,11 +284,13 @@ void make_reserved_enote_proof_v1(const SpContextualEnoteRecordV1 &contextual_re
/**
* brief: verify reserved enote proof
* param: proof - proof to verify
* param: expected_amount - amount that should be in the proof
* param: expected_amount_commitment - commitment that should be in the proof
* param: expected_onetime_address - onetime address that should be in the proof
* return: true/false according to proof validity
*/
bool verify_reserved_enote_proof_v1(const ReservedEnoteProofV1 &proof,
rct::xmr_amount expected_amount,
const rct::key &expected_amount_commitment,
const rct::key &expected_onetime_address,
const std::uint64_t expected_enote_ledger_index);
Expand Down
4 changes: 2 additions & 2 deletions tests/unit_tests/seraphis_knowledge_proofs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static void enote_knowledge_proofs_helper(const jamtis_mock_keys &keys,
amount_commitment_ref(enote_record.enote),
enote_amount_proof);

ASSERT_TRUE(verify_enote_amount_proof_v1(enote_amount_proof, enote_core.amount_commitment));
ASSERT_TRUE(verify_enote_amount_proof_v1(enote_amount_proof, enote_record.amount, enote_core.amount_commitment));

// 4. RECIPIENT: enote key image proof
EnoteKeyImageProofV1 enote_key_image_proof;
Expand Down Expand Up @@ -150,7 +150,7 @@ static void enote_knowledge_proofs_helper(const jamtis_mock_keys &keys,
EnoteSentProofV1 enote_sent_proof;
make_enote_sent_proof_v1(sender_enote_ownership_proof, enote_amount_proof, enote_sent_proof);

ASSERT_TRUE(verify_enote_sent_proof_v1(enote_sent_proof, enote_core.amount_commitment, enote_core.onetime_address));
ASSERT_TRUE(verify_enote_sent_proof_v1(enote_sent_proof, enote_record.amount, enote_core.amount_commitment, enote_core.onetime_address));
}
//-------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------
Expand Down
Loading