Transplant of libzcash.

This commit is contained in:
Sean Bowe
2016-05-04 18:26:21 -06:00
parent 2140639309
commit 2dc3599271
13 changed files with 212 additions and 237 deletions

View File

@@ -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;
}