Jack Grigg
8 years ago
9 changed files with 228 additions and 125 deletions
@ -0,0 +1,144 @@ |
|||||
|
// Copyright (c) 2016 The Zcash developers
|
||||
|
// Distributed under the MIT software license, see the accompanying
|
||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
|
||||
|
#include "utiltest.h" |
||||
|
|
||||
|
CWalletTx GetValidReceive(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, CAmount value, |
||||
|
bool randomInputs) { |
||||
|
CMutableTransaction mtx; |
||||
|
mtx.nVersion = 2; // Enable JoinSplits
|
||||
|
mtx.vin.resize(2); |
||||
|
if (randomInputs) { |
||||
|
mtx.vin[0].prevout.hash = GetRandHash(); |
||||
|
mtx.vin[1].prevout.hash = GetRandHash(); |
||||
|
} else { |
||||
|
mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); |
||||
|
mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); |
||||
|
} |
||||
|
mtx.vin[0].prevout.n = 0; |
||||
|
mtx.vin[1].prevout.n = 0; |
||||
|
|
||||
|
// Generate an ephemeral keypair.
|
||||
|
uint256 joinSplitPubKey; |
||||
|
unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; |
||||
|
crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); |
||||
|
mtx.joinSplitPubKey = joinSplitPubKey; |
||||
|
|
||||
|
boost::array<libzcash::JSInput, 2> inputs = { |
||||
|
libzcash::JSInput(), // dummy input
|
||||
|
libzcash::JSInput() // dummy input
|
||||
|
}; |
||||
|
|
||||
|
boost::array<libzcash::JSOutput, 2> outputs = { |
||||
|
libzcash::JSOutput(sk.address(), value), |
||||
|
libzcash::JSOutput(sk.address(), value) |
||||
|
}; |
||||
|
|
||||
|
boost::array<libzcash::Note, 2> output_notes; |
||||
|
|
||||
|
// Prepare JoinSplits
|
||||
|
uint256 rt; |
||||
|
JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, |
||||
|
inputs, outputs, 2*value, 0, false}; |
||||
|
mtx.vjoinsplit.push_back(jsdesc); |
||||
|
|
||||
|
// Empty output script.
|
||||
|
CScript scriptCode; |
||||
|
CTransaction signTx(mtx); |
||||
|
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); |
||||
|
|
||||
|
// Add the signature
|
||||
|
assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, |
||||
|
dataToBeSigned.begin(), 32, |
||||
|
joinSplitPrivKey |
||||
|
) == 0); |
||||
|
|
||||
|
CTransaction tx {mtx}; |
||||
|
CWalletTx wtx {NULL, tx}; |
||||
|
return wtx; |
||||
|
} |
||||
|
|
||||
|
libzcash::Note GetNote(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, |
||||
|
const CTransaction& tx, size_t js, size_t n) { |
||||
|
ZCNoteDecryption decryptor {sk.viewing_key()}; |
||||
|
auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); |
||||
|
auto note_pt = libzcash::NotePlaintext::decrypt( |
||||
|
decryptor, |
||||
|
tx.vjoinsplit[js].ciphertexts[n], |
||||
|
tx.vjoinsplit[js].ephemeralKey, |
||||
|
hSig, |
||||
|
(unsigned char) n); |
||||
|
return note_pt.note(sk.address()); |
||||
|
} |
||||
|
|
||||
|
CWalletTx GetValidSpend(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, |
||||
|
const libzcash::Note& note, CAmount value) { |
||||
|
CMutableTransaction mtx; |
||||
|
mtx.vout.resize(2); |
||||
|
mtx.vout[0].nValue = value; |
||||
|
mtx.vout[1].nValue = 0; |
||||
|
|
||||
|
// Generate an ephemeral keypair.
|
||||
|
uint256 joinSplitPubKey; |
||||
|
unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; |
||||
|
crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); |
||||
|
mtx.joinSplitPubKey = joinSplitPubKey; |
||||
|
|
||||
|
// Fake tree for the unused witness
|
||||
|
ZCIncrementalMerkleTree tree; |
||||
|
|
||||
|
libzcash::JSOutput dummyout; |
||||
|
libzcash::JSInput dummyin; |
||||
|
|
||||
|
{ |
||||
|
if (note.value > value) { |
||||
|
libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); |
||||
|
libzcash::PaymentAddress dummyaddr = dummykey.address(); |
||||
|
dummyout = libzcash::JSOutput(dummyaddr, note.value - value); |
||||
|
} else if (note.value < value) { |
||||
|
libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); |
||||
|
libzcash::PaymentAddress dummyaddr = dummykey.address(); |
||||
|
libzcash::Note dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256()); |
||||
|
tree.append(dummynote.cm()); |
||||
|
dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
tree.append(note.cm()); |
||||
|
|
||||
|
boost::array<libzcash::JSInput, 2> inputs = { |
||||
|
libzcash::JSInput(tree.witness(), note, sk), |
||||
|
dummyin |
||||
|
}; |
||||
|
|
||||
|
boost::array<libzcash::JSOutput, 2> outputs = { |
||||
|
dummyout, // dummy output
|
||||
|
libzcash::JSOutput() // dummy output
|
||||
|
}; |
||||
|
|
||||
|
boost::array<libzcash::Note, 2> output_notes; |
||||
|
|
||||
|
// Prepare JoinSplits
|
||||
|
uint256 rt = tree.root(); |
||||
|
JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, |
||||
|
inputs, outputs, 0, value, false}; |
||||
|
mtx.vjoinsplit.push_back(jsdesc); |
||||
|
|
||||
|
// Empty output script.
|
||||
|
CScript scriptCode; |
||||
|
CTransaction signTx(mtx); |
||||
|
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); |
||||
|
|
||||
|
// Add the signature
|
||||
|
assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, |
||||
|
dataToBeSigned.begin(), 32, |
||||
|
joinSplitPrivKey |
||||
|
) == 0); |
||||
|
CTransaction tx {mtx}; |
||||
|
CWalletTx wtx {NULL, tx}; |
||||
|
return wtx; |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
// Copyright (c) 2016 The Zcash developers
|
||||
|
// Distributed under the MIT software license, see the accompanying
|
||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
|
||||
|
#include "wallet/wallet.h" |
||||
|
#include "zcash/JoinSplit.hpp" |
||||
|
#include "zcash/Note.hpp" |
||||
|
#include "zcash/NoteEncryption.hpp" |
||||
|
|
||||
|
CWalletTx GetValidReceive(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, CAmount value, |
||||
|
bool randomInputs); |
||||
|
libzcash::Note GetNote(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, |
||||
|
const CTransaction& tx, size_t js, size_t n); |
||||
|
CWalletTx GetValidSpend(ZCJoinSplit& params, |
||||
|
const libzcash::SpendingKey& sk, |
||||
|
const libzcash::Note& note, CAmount value); |
Loading…
Reference in new issue