]>
Commit | Line | Data |
---|---|---|
0bb3d40f JG |
1 | // Copyright (c) 2016 The Zcash developers |
2 | // Distributed under the MIT software license, see the accompanying | |
3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | |
4 | ||
5 | #include "utiltest.h" | |
6 | ||
be126699 JG |
7 | #include "consensus/upgrades.h" |
8 | ||
0bb3d40f JG |
9 | CWalletTx GetValidReceive(ZCJoinSplit& params, |
10 | const libzcash::SpendingKey& sk, CAmount value, | |
11 | bool randomInputs) { | |
12 | CMutableTransaction mtx; | |
13 | mtx.nVersion = 2; // Enable JoinSplits | |
14 | mtx.vin.resize(2); | |
15 | if (randomInputs) { | |
16 | mtx.vin[0].prevout.hash = GetRandHash(); | |
17 | mtx.vin[1].prevout.hash = GetRandHash(); | |
18 | } else { | |
19 | mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); | |
20 | mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); | |
21 | } | |
22 | mtx.vin[0].prevout.n = 0; | |
23 | mtx.vin[1].prevout.n = 0; | |
24 | ||
25 | // Generate an ephemeral keypair. | |
26 | uint256 joinSplitPubKey; | |
27 | unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; | |
28 | crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); | |
29 | mtx.joinSplitPubKey = joinSplitPubKey; | |
30 | ||
31 | boost::array<libzcash::JSInput, 2> inputs = { | |
32 | libzcash::JSInput(), // dummy input | |
33 | libzcash::JSInput() // dummy input | |
34 | }; | |
35 | ||
36 | boost::array<libzcash::JSOutput, 2> outputs = { | |
37 | libzcash::JSOutput(sk.address(), value), | |
38 | libzcash::JSOutput(sk.address(), value) | |
39 | }; | |
40 | ||
0bb3d40f JG |
41 | // Prepare JoinSplits |
42 | uint256 rt; | |
43 | JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, | |
44 | inputs, outputs, 2*value, 0, false}; | |
45 | mtx.vjoinsplit.push_back(jsdesc); | |
46 | ||
47 | // Empty output script. | |
be126699 | 48 | uint32_t consensusBranchId = SPROUT_BRANCH_ID; |
0bb3d40f JG |
49 | CScript scriptCode; |
50 | CTransaction signTx(mtx); | |
be126699 | 51 | uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); |
0bb3d40f JG |
52 | |
53 | // Add the signature | |
54 | assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, | |
a513ea90 JG |
55 | dataToBeSigned.begin(), 32, |
56 | joinSplitPrivKey | |
57 | ) == 0); | |
0bb3d40f JG |
58 | |
59 | CTransaction tx {mtx}; | |
60 | CWalletTx wtx {NULL, tx}; | |
61 | return wtx; | |
62 | } | |
63 | ||
b230fe68 | 64 | libzcash::SproutNote GetNote(ZCJoinSplit& params, |
0bb3d40f JG |
65 | const libzcash::SpendingKey& sk, |
66 | const CTransaction& tx, size_t js, size_t n) { | |
642a1caf | 67 | ZCNoteDecryption decryptor {sk.receiving_key()}; |
0bb3d40f JG |
68 | auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); |
69 | auto note_pt = libzcash::NotePlaintext::decrypt( | |
70 | decryptor, | |
71 | tx.vjoinsplit[js].ciphertexts[n], | |
72 | tx.vjoinsplit[js].ephemeralKey, | |
73 | hSig, | |
74 | (unsigned char) n); | |
75 | return note_pt.note(sk.address()); | |
76 | } | |
77 | ||
78 | CWalletTx GetValidSpend(ZCJoinSplit& params, | |
79 | const libzcash::SpendingKey& sk, | |
b230fe68 | 80 | const libzcash::SproutNote& note, CAmount value) { |
0bb3d40f JG |
81 | CMutableTransaction mtx; |
82 | mtx.vout.resize(2); | |
83 | mtx.vout[0].nValue = value; | |
84 | mtx.vout[1].nValue = 0; | |
85 | ||
86 | // Generate an ephemeral keypair. | |
87 | uint256 joinSplitPubKey; | |
88 | unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; | |
89 | crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); | |
90 | mtx.joinSplitPubKey = joinSplitPubKey; | |
91 | ||
92 | // Fake tree for the unused witness | |
93 | ZCIncrementalMerkleTree tree; | |
94 | ||
95 | libzcash::JSOutput dummyout; | |
96 | libzcash::JSInput dummyin; | |
97 | ||
98 | { | |
5d99e3e9 | 99 | if (note.value() > value) { |
0bb3d40f JG |
100 | libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); |
101 | libzcash::PaymentAddress dummyaddr = dummykey.address(); | |
5d99e3e9 S |
102 | dummyout = libzcash::JSOutput(dummyaddr, note.value() - value); |
103 | } else if (note.value() < value) { | |
0bb3d40f JG |
104 | libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); |
105 | libzcash::PaymentAddress dummyaddr = dummykey.address(); | |
5d99e3e9 | 106 | libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value()), uint256(), uint256()); |
0bb3d40f JG |
107 | tree.append(dummynote.cm()); |
108 | dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); | |
109 | } | |
110 | } | |
111 | ||
112 | tree.append(note.cm()); | |
113 | ||
114 | boost::array<libzcash::JSInput, 2> inputs = { | |
115 | libzcash::JSInput(tree.witness(), note, sk), | |
116 | dummyin | |
117 | }; | |
118 | ||
119 | boost::array<libzcash::JSOutput, 2> outputs = { | |
120 | dummyout, // dummy output | |
121 | libzcash::JSOutput() // dummy output | |
122 | }; | |
123 | ||
0bb3d40f JG |
124 | // Prepare JoinSplits |
125 | uint256 rt = tree.root(); | |
126 | JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, | |
127 | inputs, outputs, 0, value, false}; | |
128 | mtx.vjoinsplit.push_back(jsdesc); | |
129 | ||
130 | // Empty output script. | |
be126699 | 131 | uint32_t consensusBranchId = SPROUT_BRANCH_ID; |
0bb3d40f JG |
132 | CScript scriptCode; |
133 | CTransaction signTx(mtx); | |
be126699 | 134 | uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); |
0bb3d40f JG |
135 | |
136 | // Add the signature | |
137 | assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, | |
a513ea90 JG |
138 | dataToBeSigned.begin(), 32, |
139 | joinSplitPrivKey | |
140 | ) == 0); | |
0bb3d40f JG |
141 | CTransaction tx {mtx}; |
142 | CWalletTx wtx {NULL, tx}; | |
143 | return wtx; | |
144 | } |