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