Browse Source

Check commitment validity within the decryption API for Sapling note plaintexts.

pull/4/head
Sean Bowe 6 years ago
committed by Simon
parent
commit
69c4391b0f
  1. 32
      src/gtest/test_noteencryption.cpp
  2. 43
      src/zcash/Note.cpp
  3. 6
      src/zcash/Note.hpp

32
src/gtest/test_noteencryption.cpp

@ -35,6 +35,11 @@ TEST(noteencryption, NotePlaintext)
}
SaplingNote note(addr, 39393);
auto cmu_opt = note.cm();
if (!cmu_opt) {
FAIL();
}
uint256 cmu = cmu_opt.get();
SaplingNotePlaintext pt(note, memo);
auto res = pt.encrypt(addr.pk_d);
@ -48,11 +53,20 @@ TEST(noteencryption, NotePlaintext)
auto encryptor = enc.second;
auto epk = encryptor.get_epk();
// Try to decrypt
// Try to decrypt with incorrect commitment
ASSERT_FALSE(SaplingNotePlaintext::decrypt(
ct,
ivk,
epk,
uint256()
));
// Try to decrypt with correct commitment
auto foo = SaplingNotePlaintext::decrypt(
ct,
ivk,
epk
epk,
cmu
);
if (!foo) {
@ -112,12 +126,24 @@ TEST(noteencryption, NotePlaintext)
ASSERT_TRUE(decrypted_out_ct_unwrapped.pk_d == out_pt.pk_d);
ASSERT_TRUE(decrypted_out_ct_unwrapped.esk == out_pt.esk);
// Test sender won't accept invalid commitments
ASSERT_FALSE(
SaplingNotePlaintext::decrypt(
ct,
epk,
decrypted_out_ct_unwrapped.esk,
decrypted_out_ct_unwrapped.pk_d,
uint256()
)
);
// Test sender can decrypt the note ciphertext.
foo = SaplingNotePlaintext::decrypt(
ct,
epk,
decrypted_out_ct_unwrapped.esk,
decrypted_out_ct_unwrapped.pk_d
decrypted_out_ct_unwrapped.pk_d,
cmu
);
if (!foo) {

43
src/zcash/Note.cpp

@ -187,7 +187,8 @@ boost::optional<SaplingOutgoingPlaintext> SaplingOutgoingPlaintext::decrypt(
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
const SaplingEncCiphertext &ciphertext,
const uint256 &ivk,
const uint256 &epk
const uint256 &epk,
const uint256 &cmu
)
{
auto pt = AttemptSaplingEncDecryption(ciphertext, ivk, epk);
@ -204,6 +205,27 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
assert(ss.size() == 0);
uint256 pk_d;
if (!librustzcash_ivk_to_pkd(ivk.begin(), ret.d.data(), pk_d.begin())) {
return boost::none;
}
uint256 cmu_expected;
if (!librustzcash_sapling_compute_cm(
ret.d.data(),
pk_d.begin(),
ret.value(),
ret.rcm.begin(),
cmu_expected.begin()
))
{
return boost::none;
}
if (cmu_expected != cmu) {
return boost::none;
}
return ret;
}
@ -211,7 +233,8 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d
const uint256 &pk_d,
const uint256 &cmu
)
{
auto pt = AttemptSaplingEncDecryption(ciphertext, epk, esk, pk_d);
@ -226,6 +249,22 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
SaplingNotePlaintext ret;
ss >> ret;
uint256 cmu_expected;
if (!librustzcash_sapling_compute_cm(
ret.d.data(),
pk_d.begin(),
ret.value(),
ret.rcm.begin(),
cmu_expected.begin()
))
{
return boost::none;
}
if (cmu_expected != cmu) {
return boost::none;
}
assert(ss.size() == 0);
return ret;

6
src/zcash/Note.hpp

@ -130,14 +130,16 @@ public:
static boost::optional<SaplingNotePlaintext> decrypt(
const SaplingEncCiphertext &ciphertext,
const uint256 &ivk,
const uint256 &epk
const uint256 &epk,
const uint256 &cmu
);
static boost::optional<SaplingNotePlaintext> decrypt(
const SaplingEncCiphertext &ciphertext,
const uint256 &epk,
const uint256 &esk,
const uint256 &pk_d
const uint256 &pk_d,
const uint256 &cmu
);
boost::optional<SaplingNote> note(const SaplingIncomingViewingKey& ivk) const;

Loading…
Cancel
Save