2016-05-04 17:25:42 -07:00
|
|
|
#include "Note.hpp"
|
|
|
|
#include "prf.h"
|
|
|
|
#include "crypto/sha256.h"
|
|
|
|
|
2018-06-08 15:25:15 -07:00
|
|
|
#include "random.h"
|
2016-05-04 17:25:42 -07:00
|
|
|
#include "version.h"
|
|
|
|
#include "streams.h"
|
|
|
|
|
2016-05-12 12:19:13 -07:00
|
|
|
#include "zcash/util.h"
|
2018-06-08 15:25:15 -07:00
|
|
|
#include "librustzcash.h"
|
2016-05-12 12:19:13 -07:00
|
|
|
|
2018-06-12 10:01:20 -07:00
|
|
|
using namespace libzcash;
|
2016-05-04 17:25:42 -07:00
|
|
|
|
2018-04-24 21:20:01 -07:00
|
|
|
SproutNote::SproutNote() {
|
2016-05-04 17:25:42 -07:00
|
|
|
a_pk = random_uint256();
|
|
|
|
rho = random_uint256();
|
|
|
|
r = random_uint256();
|
|
|
|
}
|
|
|
|
|
2018-04-24 21:20:01 -07:00
|
|
|
uint256 SproutNote::cm() const {
|
2016-05-04 17:25:42 -07:00
|
|
|
unsigned char discriminant = 0xb0;
|
|
|
|
|
|
|
|
CSHA256 hasher;
|
|
|
|
hasher.Write(&discriminant, 1);
|
|
|
|
hasher.Write(a_pk.begin(), 32);
|
|
|
|
|
2018-04-25 13:32:13 -07:00
|
|
|
auto value_vec = convertIntToVectorLE(value_);
|
2016-05-04 17:25:42 -07:00
|
|
|
|
|
|
|
hasher.Write(&value_vec[0], value_vec.size());
|
|
|
|
hasher.Write(rho.begin(), 32);
|
|
|
|
hasher.Write(r.begin(), 32);
|
|
|
|
|
|
|
|
uint256 result;
|
|
|
|
hasher.Finalize(result.begin());
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const {
|
2016-05-04 17:25:42 -07:00
|
|
|
return PRF_nf(a_sk, rho);
|
|
|
|
}
|
|
|
|
|
2018-06-12 09:36:38 -07:00
|
|
|
// Construct and populate Sapling note for a given payment address and value.
|
|
|
|
SaplingNote::SaplingNote(const SaplingPaymentAddress& address, const uint64_t value) : BaseNote(value) {
|
|
|
|
d = address.d;
|
|
|
|
pk_d = address.pk_d;
|
2018-06-08 15:25:15 -07:00
|
|
|
librustzcash_sapling_generate_r(r.begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Call librustzcash to compute the commitment
|
2018-06-12 10:01:20 -07:00
|
|
|
boost::optional<uint256> SaplingNote::cm() const {
|
2018-06-08 15:25:15 -07:00
|
|
|
uint256 result;
|
|
|
|
if (!librustzcash_sapling_compute_cm(
|
|
|
|
d.data(),
|
|
|
|
pk_d.begin(),
|
|
|
|
value(),
|
|
|
|
r.begin(),
|
|
|
|
result.begin()
|
|
|
|
))
|
|
|
|
{
|
2018-06-12 10:01:20 -07:00
|
|
|
return boost::none;
|
2018-06-08 15:25:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Call librustzcash to compute the nullifier
|
2018-06-12 10:01:20 -07:00
|
|
|
boost::optional<uint256> SaplingNote::nullifier(const SaplingSpendingKey& sk, const uint64_t position) const
|
2018-06-08 15:25:15 -07:00
|
|
|
{
|
|
|
|
auto vk = sk.full_viewing_key();
|
|
|
|
auto ak = vk.ak;
|
|
|
|
auto nk = vk.nk;
|
|
|
|
|
|
|
|
uint256 result;
|
|
|
|
if (!librustzcash_sapling_compute_nf(
|
|
|
|
d.data(),
|
|
|
|
pk_d.begin(),
|
|
|
|
value(),
|
|
|
|
r.begin(),
|
|
|
|
ak.begin(),
|
|
|
|
nk.begin(),
|
|
|
|
position,
|
|
|
|
result.begin()
|
|
|
|
))
|
|
|
|
{
|
2018-06-12 10:01:20 -07:00
|
|
|
return boost::none;
|
2018-06-08 15:25:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-25 23:08:36 -07:00
|
|
|
SproutNotePlaintext::SproutNotePlaintext(
|
2018-04-24 21:20:01 -07:00
|
|
|
const SproutNote& note,
|
2018-05-03 03:53:51 -07:00
|
|
|
std::array<unsigned char, ZC_MEMO_SIZE> memo) : BaseNotePlaintext(note, memo)
|
2016-05-04 17:25:42 -07:00
|
|
|
{
|
|
|
|
rho = note.rho;
|
|
|
|
r = note.r;
|
|
|
|
}
|
|
|
|
|
2018-04-25 18:51:17 -07:00
|
|
|
SproutNote SproutNotePlaintext::note(const SproutPaymentAddress& addr) const
|
2016-05-04 17:25:42 -07:00
|
|
|
{
|
2018-04-26 14:05:36 -07:00
|
|
|
return SproutNote(addr.a_pk, value_, rho, r);
|
2016-05-04 17:25:42 -07:00
|
|
|
}
|
|
|
|
|
2018-04-25 23:08:36 -07:00
|
|
|
SproutNotePlaintext SproutNotePlaintext::decrypt(const ZCNoteDecryption& decryptor,
|
2016-05-04 17:25:42 -07:00
|
|
|
const ZCNoteDecryption::Ciphertext& ciphertext,
|
|
|
|
const uint256& ephemeralKey,
|
|
|
|
const uint256& h_sig,
|
|
|
|
unsigned char nonce
|
|
|
|
)
|
|
|
|
{
|
|
|
|
auto plaintext = decryptor.decrypt(ciphertext, ephemeralKey, h_sig, nonce);
|
|
|
|
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
ss << plaintext;
|
|
|
|
|
2018-04-25 23:08:36 -07:00
|
|
|
SproutNotePlaintext ret;
|
2016-05-04 17:25:42 -07:00
|
|
|
ss >> ret;
|
|
|
|
|
|
|
|
assert(ss.size() == 0);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-04-25 23:08:36 -07:00
|
|
|
ZCNoteEncryption::Ciphertext SproutNotePlaintext::encrypt(ZCNoteEncryption& encryptor,
|
2016-05-04 17:25:42 -07:00
|
|
|
const uint256& pk_enc
|
|
|
|
) const
|
|
|
|
{
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
|
|
ss << (*this);
|
|
|
|
|
|
|
|
ZCNoteEncryption::Plaintext pt;
|
|
|
|
|
|
|
|
assert(pt.size() == ss.size());
|
|
|
|
|
|
|
|
memcpy(&pt[0], &ss[0], pt.size());
|
|
|
|
|
|
|
|
return encryptor.encrypt(pk_enc, pt);
|
|
|
|
}
|