(wallet) Check that the commitment matches the note plaintext provided by the sender.

This commit is contained in:
Sean Bowe 2019-03-19 01:46:27 -06:00
parent 1cbe5075d6
commit c1009374b1
4 changed files with 65 additions and 1 deletions

View File

@ -10,7 +10,7 @@
#include <array>
// Sprout
CWalletTx GetValidSproutReceive(ZCJoinSplit& params,
CMutableTransaction GetValidSproutReceiveTransaction(ZCJoinSplit& params,
const libzcash::SproutSpendingKey& sk,
CAmount value,
bool randomInputs,
@ -71,6 +71,34 @@ CWalletTx GetValidSproutReceive(ZCJoinSplit& params,
joinSplitPrivKey
) == 0);
return mtx;
}
CWalletTx GetValidSproutReceive(ZCJoinSplit& params,
const libzcash::SproutSpendingKey& sk,
CAmount value,
bool randomInputs,
int32_t version /* = 2 */)
{
CMutableTransaction mtx = GetValidSproutReceiveTransaction(
params, sk, value, randomInputs, version
);
CTransaction tx {mtx};
CWalletTx wtx {NULL, tx};
return wtx;
}
CWalletTx GetInvalidCommitmentSproutReceive(ZCJoinSplit& params,
const libzcash::SproutSpendingKey& sk,
CAmount value,
bool randomInputs,
int32_t version /* = 2 */)
{
CMutableTransaction mtx = GetValidSproutReceiveTransaction(
params, sk, value, randomInputs, version
);
mtx.vjoinsplit[0].commitments[0] = uint256();
mtx.vjoinsplit[0].commitments[1] = uint256();
CTransaction tx {mtx};
CWalletTx wtx {NULL, tx};
return wtx;

View File

@ -18,6 +18,11 @@ CWalletTx GetValidSproutReceive(ZCJoinSplit& params,
CAmount value,
bool randomInputs,
int32_t version = 2);
CWalletTx GetInvalidCommitmentSproutReceive(ZCJoinSplit& params,
const libzcash::SproutSpendingKey& sk,
CAmount value,
bool randomInputs,
int32_t version = 2);
libzcash::SproutNote GetSproutNote(ZCJoinSplit& params,
const libzcash::SproutSpendingKey& sk,
const CTransaction& tx, size_t js, size_t n);

View File

@ -75,6 +75,10 @@ CWalletTx GetValidSproutReceive(const libzcash::SproutSpendingKey& sk, CAmount v
return GetValidSproutReceive(*params, sk, value, randomInputs, version);
}
CWalletTx GetInvalidCommitmentSproutReceive(const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs, int32_t version = 2) {
return GetInvalidCommitmentSproutReceive(*params, sk, value, randomInputs, version);
}
libzcash::SproutNote GetSproutNote(const libzcash::SproutSpendingKey& sk,
const CTransaction& tx, size_t js, size_t n) {
return GetSproutNote(*params, sk, tx, js, n);
@ -436,6 +440,27 @@ TEST(WalletTests, SetInvalidSaplingNoteDataInCWalletTx) {
EXPECT_THROW(wtx.SetSaplingNoteData(noteData), std::logic_error);
}
TEST(WalletTests, CheckSproutNoteCommitmentAgainstNotePlaintext) {
CWallet wallet;
auto sk = libzcash::SproutSpendingKey::random();
auto address = sk.address();
auto dec = ZCNoteDecryption(sk.receiving_key());
auto wtx = GetInvalidCommitmentSproutReceive(sk, 10, true);
auto note = GetSproutNote(sk, wtx, 0, 1);
auto nullifier = note.nullifier(sk);
auto hSig = wtx.vjoinsplit[0].h_sig(
*params, wtx.joinSplitPubKey);
ASSERT_THROW(wallet.GetSproutNoteNullifier(
wtx.vjoinsplit[0],
address,
dec,
hSig, 1), libzcash::note_decryption_failed);
}
TEST(WalletTests, GetSproutNoteNullifier) {
CWallet wallet;

View File

@ -1699,6 +1699,12 @@ boost::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &js
hSig,
(unsigned char) n);
auto note = note_pt.note(address);
// Check note plaintext against note commitment
if (note.cm() != jsdesc.commitments[n]) {
throw libzcash::note_decryption_failed();
}
// SpendingKeys are only available if:
// - We have them (this isn't a viewing key)
// - The wallet is unlocked