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