Implement Sapling note decryption using full viewing key.
This commit is contained in:
parent
687bd96cbd
commit
7b913c3e5e
|
@ -111,6 +111,25 @@ 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 can decrypt the note ciphertext.
|
||||
foo = SaplingNotePlaintext::decryptUsingFullViewingKey(
|
||||
ct,
|
||||
epk,
|
||||
decrypted_out_ct_unwrapped.esk,
|
||||
decrypted_out_ct_unwrapped.pk_d
|
||||
);
|
||||
|
||||
if (!foo) {
|
||||
FAIL();
|
||||
}
|
||||
|
||||
bar = foo.get();
|
||||
|
||||
ASSERT_TRUE(bar.value() == pt.value());
|
||||
ASSERT_TRUE(bar.memo() == pt.memo());
|
||||
ASSERT_TRUE(bar.d == pt.d);
|
||||
ASSERT_TRUE(bar.rcm == pt.rcm);
|
||||
}
|
||||
|
||||
TEST(noteencryption, SaplingApi)
|
||||
|
|
|
@ -208,6 +208,30 @@ boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decrypt(
|
|||
return ret;
|
||||
}
|
||||
|
||||
boost::optional<SaplingNotePlaintext> SaplingNotePlaintext::decryptUsingFullViewingKey(
|
||||
const SaplingEncCiphertext &ciphertext,
|
||||
const uint256 &epk,
|
||||
const uint256 &esk,
|
||||
const uint256 &pk_d
|
||||
)
|
||||
{
|
||||
auto pt = AttemptSaplingEncDecryptionUsingFullViewingKey(ciphertext, epk, esk, pk_d);
|
||||
if (!pt) {
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
// Deserialize from the plaintext
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << pt.get();
|
||||
|
||||
SaplingNotePlaintext ret;
|
||||
ss >> ret;
|
||||
|
||||
assert(ss.size() == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
boost::optional<SaplingNotePlaintextEncryptionResult> SaplingNotePlaintext::encrypt(const uint256& pk_d) const
|
||||
{
|
||||
// Get the encryptor
|
||||
|
|
|
@ -133,6 +133,13 @@ public:
|
|||
const uint256 &epk
|
||||
);
|
||||
|
||||
static boost::optional<SaplingNotePlaintext> decryptUsingFullViewingKey(
|
||||
const SaplingEncCiphertext &ciphertext,
|
||||
const uint256 &epk,
|
||||
const uint256 &esk,
|
||||
const uint256 &pk_d
|
||||
);
|
||||
|
||||
boost::optional<SaplingNote> note(const SaplingIncomingViewingKey& ivk) const;
|
||||
|
||||
virtual ~SaplingNotePlaintext() {}
|
||||
|
|
|
@ -187,6 +187,43 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
|
|||
return plaintext;
|
||||
}
|
||||
|
||||
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryptionUsingFullViewingKey (
|
||||
const SaplingEncCiphertext &ciphertext,
|
||||
const uint256 &epk,
|
||||
const uint256 &esk,
|
||||
const uint256 &pk_d
|
||||
)
|
||||
{
|
||||
uint256 dhsecret;
|
||||
|
||||
if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) {
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
// Construct the symmetric key
|
||||
unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE];
|
||||
KDF_Sapling(K, dhsecret, epk);
|
||||
|
||||
// The nonce is zero because we never reuse keys
|
||||
unsigned char cipher_nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES] = {};
|
||||
|
||||
SaplingEncPlaintext plaintext;
|
||||
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
plaintext.begin(), NULL,
|
||||
NULL,
|
||||
ciphertext.begin(), ZC_SAPLING_ENCCIPHERTEXT_SIZE,
|
||||
NULL,
|
||||
0,
|
||||
cipher_nonce, K) != 0)
|
||||
{
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
|
||||
SaplingOutCiphertext SaplingNoteEncryption::encrypt_to_ourselves(
|
||||
const uint256 &ovk,
|
||||
const uint256 &cv,
|
||||
|
|
|
@ -73,6 +73,15 @@ boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryption(
|
|||
const uint256 &epk
|
||||
);
|
||||
|
||||
// Attempts to decrypt a Sapling note using full viewing key.
|
||||
// This will not check that the contents of the ciphertext are correct.
|
||||
boost::optional<SaplingEncPlaintext> AttemptSaplingEncDecryptionUsingFullViewingKey (
|
||||
const SaplingEncCiphertext &ciphertext,
|
||||
const uint256 &epk,
|
||||
const uint256 &esk,
|
||||
const uint256 &pk_d
|
||||
);
|
||||
|
||||
// Attempts to decrypt a Sapling note. This will not check that the contents
|
||||
// of the ciphertext are correct.
|
||||
boost::optional<SaplingOutPlaintext> AttemptSaplingOutDecryption(
|
||||
|
|
Loading…
Reference in New Issue