Auto merge of #2159 - bitcartel:1.0.7_payment_disclosure, r=str4d
Payment disclosure (experimental feature)
This commit is contained in:
@@ -150,7 +150,8 @@ public:
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt,
|
||||
bool computeProof
|
||||
bool computeProof,
|
||||
uint256 *out_esk // Payment disclosure
|
||||
) {
|
||||
if (vpub_old > MAX_MONEY) {
|
||||
throw std::invalid_argument("nonsensical vpub_old value");
|
||||
@@ -251,6 +252,12 @@ public:
|
||||
}
|
||||
|
||||
out_ephemeralKey = encryptor.get_epk();
|
||||
|
||||
// !!! Payment disclosure START
|
||||
if (out_esk != nullptr) {
|
||||
*out_esk = encryptor.get_esk();
|
||||
}
|
||||
// !!! Payment disclosure END
|
||||
}
|
||||
|
||||
// Authenticate h_sig with each of the input
|
||||
|
||||
@@ -73,7 +73,11 @@ public:
|
||||
uint64_t vpub_old,
|
||||
uint64_t vpub_new,
|
||||
const uint256& rt,
|
||||
bool computeProof = true
|
||||
bool computeProof = true,
|
||||
// For paymentdisclosure, we need to retrieve the esk.
|
||||
// Reference as non-const parameter with default value leads to compile error.
|
||||
// So use pointer for simplicity.
|
||||
uint256 *out_esk = nullptr
|
||||
) = 0;
|
||||
|
||||
virtual bool verify(
|
||||
|
||||
@@ -135,6 +135,52 @@ typename NoteDecryption<MLEN>::Plaintext NoteDecryption<MLEN>::decrypt
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
//
|
||||
// Payment disclosure - decrypt with esk
|
||||
//
|
||||
template<size_t MLEN>
|
||||
typename PaymentDisclosureNoteDecryption<MLEN>::Plaintext PaymentDisclosureNoteDecryption<MLEN>::decryptWithEsk
|
||||
(const PaymentDisclosureNoteDecryption<MLEN>::Ciphertext &ciphertext,
|
||||
const uint256 &pk_enc,
|
||||
const uint256 &esk,
|
||||
const uint256 &hSig,
|
||||
unsigned char nonce
|
||||
) const
|
||||
{
|
||||
uint256 dhsecret;
|
||||
|
||||
if (crypto_scalarmult(dhsecret.begin(), esk.begin(), pk_enc.begin()) != 0) {
|
||||
throw std::logic_error("Could not create DH secret");
|
||||
}
|
||||
|
||||
// Regenerate keypair
|
||||
uint256 epk = NoteEncryption<MLEN>::generate_pubkey(esk);
|
||||
|
||||
unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE];
|
||||
KDF(K, dhsecret, epk, pk_enc, hSig, nonce);
|
||||
|
||||
// The nonce is zero because we never reuse keys
|
||||
unsigned char cipher_nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES] = {};
|
||||
|
||||
PaymentDisclosureNoteDecryption<MLEN>::Plaintext plaintext;
|
||||
|
||||
// Message length is always NOTEENCRYPTION_AUTH_BYTES less than
|
||||
// the ciphertext length.
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(plaintext.begin(), NULL,
|
||||
NULL,
|
||||
ciphertext.begin(), PaymentDisclosureNoteDecryption<MLEN>::CLEN,
|
||||
NULL,
|
||||
0,
|
||||
cipher_nonce, K) != 0) {
|
||||
throw note_decryption_failed();
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<size_t MLEN>
|
||||
uint256 NoteEncryption<MLEN>::generate_privkey(const uint252 &a_sk)
|
||||
{
|
||||
@@ -176,4 +222,6 @@ uint252 random_uint252()
|
||||
template class NoteEncryption<ZC_NOTEPLAINTEXT_SIZE>;
|
||||
template class NoteDecryption<ZC_NOTEPLAINTEXT_SIZE>;
|
||||
|
||||
template class PaymentDisclosureNoteDecryption<ZC_NOTEPLAINTEXT_SIZE>;
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ public:
|
||||
|
||||
NoteEncryption(uint256 hSig);
|
||||
|
||||
// Gets the ephemeral secret key
|
||||
uint256 get_esk() {
|
||||
return esk;
|
||||
}
|
||||
|
||||
// Gets the ephemeral public key
|
||||
uint256 get_epk() {
|
||||
return epk;
|
||||
@@ -87,9 +92,34 @@ public:
|
||||
note_decryption_failed() : std::runtime_error("Could not decrypt message") { }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Subclass PaymentDisclosureNoteDecryption provides a method to decrypt a note with esk.
|
||||
template<size_t MLEN>
|
||||
class PaymentDisclosureNoteDecryption : public NoteDecryption<MLEN> {
|
||||
protected:
|
||||
public:
|
||||
enum { CLEN=MLEN+NOTEENCRYPTION_AUTH_BYTES };
|
||||
typedef boost::array<unsigned char, CLEN> Ciphertext;
|
||||
typedef boost::array<unsigned char, MLEN> Plaintext;
|
||||
|
||||
PaymentDisclosureNoteDecryption() : NoteDecryption<MLEN>() {}
|
||||
PaymentDisclosureNoteDecryption(uint256 sk_enc) : NoteDecryption<MLEN>(sk_enc) {}
|
||||
|
||||
Plaintext decryptWithEsk(
|
||||
const Ciphertext &ciphertext,
|
||||
const uint256 &pk_enc,
|
||||
const uint256 &esk,
|
||||
const uint256 &hSig,
|
||||
unsigned char nonce
|
||||
) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef libzcash::NoteEncryption<ZC_NOTEPLAINTEXT_SIZE> ZCNoteEncryption;
|
||||
typedef libzcash::NoteDecryption<ZC_NOTEPLAINTEXT_SIZE> ZCNoteDecryption;
|
||||
|
||||
typedef libzcash::PaymentDisclosureNoteDecryption<ZC_NOTEPLAINTEXT_SIZE> ZCPaymentDisclosureNoteDecryption;
|
||||
|
||||
#endif /* ZC_NOTE_ENCRYPTION_H_ */
|
||||
|
||||
Reference in New Issue
Block a user