Transplant of libzcash.
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
using namespace libzcash;
|
||||
|
||||
int64_t nWalletUnlockTime;
|
||||
static CCriticalSection cs_nWalletUnlockTime;
|
||||
|
||||
@@ -2385,7 +2387,7 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp)
|
||||
if (benchmarktype == "createjoinsplit") {
|
||||
/* Load the proving now key so that it doesn't happen as part of the
|
||||
* first joinsplit. */
|
||||
pzerocashParams->loadProvingKey();
|
||||
pzcashParams->loadProvingKey();
|
||||
}
|
||||
|
||||
for (int i = 0; i < samplecount; i++) {
|
||||
@@ -2454,14 +2456,12 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
uint256 a_sk;
|
||||
uint256 sk_enc;
|
||||
SpendingKey k;
|
||||
|
||||
{
|
||||
CDataStream ssData(ParseHexV(params[0], "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssData >> a_sk;
|
||||
ssData >> sk_enc;
|
||||
ssData >> k;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"zcsecretkey could not be decoded"
|
||||
@@ -2469,12 +2469,10 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
|
||||
libzerocash::Address zcaddress(zcsecretkey);
|
||||
|
||||
uint256 epk;
|
||||
unsigned char nonce;
|
||||
ZCNoteEncryption::Ciphertext ct;
|
||||
uint256 h_sig;
|
||||
|
||||
{
|
||||
CDataStream ssData(ParseHexV(params[1], "encrypted_bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
@@ -2482,6 +2480,7 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
||||
ssData >> nonce;
|
||||
ssData >> epk;
|
||||
ssData >> ct;
|
||||
ssData >> h_sig;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"encrypted_bucket could not be decoded"
|
||||
@@ -2489,32 +2488,40 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
libzerocash::Coin decrypted_bucket(ct, zcaddress, epk, nonce);
|
||||
ZCNoteDecryption decryptor(k.viewing_key());
|
||||
|
||||
std::vector<unsigned char> commitment_v = decrypted_bucket.getCoinCommitment().getCommitmentValue();
|
||||
uint256 commitment = uint256(commitment_v);
|
||||
NotePlaintext npt = NotePlaintext::decrypt(
|
||||
decryptor,
|
||||
ct,
|
||||
epk,
|
||||
h_sig,
|
||||
nonce
|
||||
);
|
||||
PaymentAddress payment_addr = k.address();
|
||||
Note decrypted_note = npt.note(payment_addr);
|
||||
|
||||
assert(pwalletMain != NULL);
|
||||
libzcash::MerklePath path;
|
||||
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
||||
uint256 anchor;
|
||||
auto found_in_chain = pwalletMain->WitnessBucketCommitment(commitment, path, anchor);
|
||||
|
||||
CAmount value_of_bucket = decrypted_bucket.getValue();
|
||||
uint256 commitment = decrypted_note.cm();
|
||||
pwalletMain->WitnessBucketCommitment(
|
||||
{commitment},
|
||||
witnesses,
|
||||
anchor
|
||||
);
|
||||
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
{
|
||||
ss << decrypted_bucket.getValue();
|
||||
ss << decrypted_bucket.getRho();
|
||||
ss << decrypted_bucket.getR();
|
||||
}
|
||||
ss << npt;
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("amount", ValueFromAmount(value_of_bucket)));
|
||||
result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value)));
|
||||
result.push_back(Pair("bucket", HexStr(ss.begin(), ss.end())));
|
||||
result.push_back(Pair("exists", found_in_chain));
|
||||
result.push_back(Pair("exists", (bool) witnesses[0]));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp)) {
|
||||
@@ -2563,30 +2570,20 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
if (params[4].get_real() != 0.0)
|
||||
vpub_new = AmountFromValue(params[4]);
|
||||
|
||||
std::vector<PourInput> vpourin;
|
||||
std::vector<PourOutput> vpourout;
|
||||
|
||||
uint256 anchor;
|
||||
std::vector<JSInput> vpourin;
|
||||
std::vector<JSOutput> vpourout;
|
||||
std::vector<Note> notes;
|
||||
std::vector<SpendingKey> keys;
|
||||
std::vector<uint256> commitments;
|
||||
|
||||
BOOST_FOREACH(const Pair& s, inputs)
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
uint64_t value;
|
||||
std::vector<unsigned char> rho;
|
||||
std::vector<unsigned char> r;
|
||||
|
||||
ssData >> value;
|
||||
ssData >> rho;
|
||||
ssData >> r;
|
||||
|
||||
uint256 a_sk;
|
||||
uint256 sk_enc;
|
||||
SpendingKey k;
|
||||
|
||||
{
|
||||
CDataStream ssData2(ParseHexV(s.value_, "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream ssData(ParseHexV(s.value_, "zcsecretkey"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
try {
|
||||
ssData2 >> a_sk;
|
||||
ssData2 >> sk_enc;
|
||||
ssData >> k;
|
||||
} catch(const std::exception &) {
|
||||
throw runtime_error(
|
||||
"zcsecretkey could not be decoded"
|
||||
@@ -2594,51 +2591,58 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
libzerocash::PrivateAddress zcsecretkey(a_sk, sk_enc);
|
||||
libzerocash::Address zcaddress(zcsecretkey);
|
||||
libzerocash::Coin input_coin(zcaddress.getPublicAddress(), value, rho, r);
|
||||
keys.push_back(k);
|
||||
|
||||
std::vector<unsigned char> commitment_v = input_coin.getCoinCommitment().getCommitmentValue();
|
||||
uint256 commitment = uint256(commitment_v);
|
||||
NotePlaintext npt;
|
||||
|
||||
libzcash::MerklePath path;
|
||||
assert(pwalletMain != NULL);
|
||||
if (!pwalletMain->WitnessBucketCommitment(commitment, path, anchor)) {
|
||||
throw std::runtime_error("Couldn't find bucket in the blockchain");
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "bucket"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
ssData >> npt;
|
||||
}
|
||||
|
||||
vpourin.push_back(PourInput(input_coin, zcaddress, path));
|
||||
PaymentAddress addr = k.address();
|
||||
Note note = npt.note(addr);
|
||||
notes.push_back(note);
|
||||
commitments.push_back(note.cm());
|
||||
}
|
||||
|
||||
uint256 anchor;
|
||||
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
||||
pwalletMain->WitnessBucketCommitment(commitments, witnesses, anchor);
|
||||
|
||||
assert(witnesses.size() == notes.size());
|
||||
assert(notes.size() == keys.size());
|
||||
|
||||
{
|
||||
for (size_t i = 0; i < witnesses.size(); i++) {
|
||||
if (!witnesses[i]) {
|
||||
throw runtime_error(
|
||||
"pour input could not be found in tree"
|
||||
);
|
||||
}
|
||||
|
||||
vpourin.push_back(JSInput(*witnesses[i], notes[i], keys[i]));
|
||||
}
|
||||
}
|
||||
|
||||
while (vpourin.size() < ZC_NUM_JS_INPUTS) {
|
||||
vpourin.push_back(PourInput(INCREMENTAL_MERKLE_TREE_DEPTH));
|
||||
vpourin.push_back(JSInput());
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const Pair& s, outputs)
|
||||
{
|
||||
libzerocash::PublicAddress addrTo;
|
||||
|
||||
PaymentAddress addrTo;
|
||||
{
|
||||
CDataStream ssData(ParseHexV(s.name_, "to_address"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
uint256 pubAddressSecret;
|
||||
uint256 encryptionPublicKey;
|
||||
|
||||
ssData >> pubAddressSecret;
|
||||
ssData >> encryptionPublicKey;
|
||||
|
||||
addrTo = libzerocash::PublicAddress(pubAddressSecret, encryptionPublicKey);
|
||||
ssData >> addrTo;
|
||||
}
|
||||
CAmount nAmount = AmountFromValue(s.value_);
|
||||
|
||||
libzerocash::Coin coin(addrTo, nAmount);
|
||||
libzerocash::PourOutput output(coin, addrTo);
|
||||
|
||||
vpourout.push_back(output);
|
||||
vpourout.push_back(JSOutput(addrTo, nAmount));
|
||||
}
|
||||
|
||||
while (vpourout.size() < ZC_NUM_JS_OUTPUTS) {
|
||||
vpourout.push_back(PourOutput(0));
|
||||
vpourout.push_back(JSOutput());
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -2648,7 +2652,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
|
||||
// TODO: #808
|
||||
uint256 pubKeyHash;
|
||||
CPourTx pourtx(*pzerocashParams,
|
||||
CPourTx pourtx(*pzcashParams,
|
||||
pubKeyHash,
|
||||
anchor,
|
||||
{vpourin[0], vpourin[1]},
|
||||
@@ -2656,7 +2660,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
vpub_old,
|
||||
vpub_new);
|
||||
|
||||
assert(pourtx.Verify(*pzerocashParams, pubKeyHash));
|
||||
assert(pourtx.Verify(*pzcashParams, pubKeyHash));
|
||||
|
||||
CMutableTransaction mtx(tx);
|
||||
mtx.nVersion = 2;
|
||||
@@ -2674,6 +2678,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
ss2 << ((unsigned char) 0x00);
|
||||
ss2 << pourtx.ephemeralKey;
|
||||
ss2 << pourtx.ciphertexts[0];
|
||||
ss2 << pourtx.h_sig(*pzcashParams, pubKeyHash);
|
||||
|
||||
encryptedBucket1 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
@@ -2682,6 +2687,7 @@ Value zc_raw_pour(const json_spirit::Array& params, bool fHelp)
|
||||
ss2 << ((unsigned char) 0x01);
|
||||
ss2 << pourtx.ephemeralKey;
|
||||
ss2 << pourtx.ciphertexts[1];
|
||||
ss2 << pourtx.h_sig(*pzcashParams, pubKeyHash);
|
||||
|
||||
encryptedBucket2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
@@ -2712,22 +2718,25 @@ Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp)
|
||||
);
|
||||
}
|
||||
|
||||
auto zckeypair = libzerocash::Address::CreateNewRandomAddress();
|
||||
auto k = SpendingKey::random();
|
||||
auto addr = k.address();
|
||||
auto viewing_key = k.viewing_key();
|
||||
|
||||
CDataStream pub(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream priv(SER_NETWORK, PROTOCOL_VERSION);
|
||||
CDataStream viewing(SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
pub << zckeypair.getPublicAddress().getPublicAddressSecret(); // a_pk
|
||||
pub << zckeypair.getPublicAddress().getEncryptionPublicKey(); // pk_enc
|
||||
|
||||
priv << zckeypair.getPrivateAddress().getAddressSecret(); // a_sk
|
||||
priv << zckeypair.getPrivateAddress().getEncryptionSecretKey(); // sk_enc
|
||||
pub << addr;
|
||||
priv << k;
|
||||
viewing << viewing_key;
|
||||
|
||||
std::string pub_hex = HexStr(pub.begin(), pub.end());
|
||||
std::string priv_hex = HexStr(priv.begin(), priv.end());
|
||||
std::string viewing_hex = HexStr(viewing.begin(), viewing.end());
|
||||
|
||||
Object result;
|
||||
result.push_back(Pair("zcaddress", pub_hex));
|
||||
result.push_back(Pair("zcsecretkey", priv_hex));
|
||||
result.push_back(Pair("zcviewingkey", viewing_hex));
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user