]> Git Repo - VerusCoin.git/blame - src/zcash/circuit/note.tcc
Refactoring: SproutNote member variable value moved to BaseNote.
[VerusCoin.git] / src / zcash / circuit / note.tcc
CommitLineData
ca8d6c93
SB
1template<typename FieldT>
2class note_gadget : public gadget<FieldT> {
3public:
4 pb_variable_array<FieldT> value;
5 std::shared_ptr<digest_variable<FieldT>> r;
6
7 note_gadget(protoboard<FieldT> &pb) : gadget<FieldT>(pb) {
8 value.allocate(pb, 64);
9 r.reset(new digest_variable<FieldT>(pb, 256, ""));
10 }
11
12 void generate_r1cs_constraints() {
13 for (size_t i = 0; i < 64; i++) {
14 generate_boolean_r1cs_constraint<FieldT>(
15 this->pb,
16 value[i],
17 "boolean_value"
18 );
19 }
20
21 r->generate_r1cs_constraints();
22 }
23
b230fe68 24 void generate_r1cs_witness(const SproutNote& note) {
ca8d6c93 25 r->bits.fill_with_bits(this->pb, uint256_to_bool_vector(note.r));
5d99e3e9 26 value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value()));
ca8d6c93
SB
27 }
28};
29
30template<typename FieldT>
31class input_note_gadget : public note_gadget<FieldT> {
e52f40e8 32private:
ca8d6c93 33 std::shared_ptr<digest_variable<FieldT>> a_pk;
2a2f3fb8 34 std::shared_ptr<digest_variable<FieldT>> rho;
ca8d6c93 35
fcece37f
SB
36 std::shared_ptr<digest_variable<FieldT>> commitment;
37 std::shared_ptr<note_commitment_gadget<FieldT>> commit_to_inputs;
38
59c3d926
SB
39 pb_variable<FieldT> value_enforce;
40 std::shared_ptr<merkle_tree_gadget<FieldT>> witness_input;
41
ca8d6c93 42 std::shared_ptr<PRF_addr_a_pk_gadget<FieldT>> spend_authority;
2a2f3fb8 43 std::shared_ptr<PRF_nf_gadget<FieldT>> expose_nullifiers;
e52f40e8
SB
44public:
45 std::shared_ptr<digest_variable<FieldT>> a_sk;
ca8d6c93
SB
46
47 input_note_gadget(
48 protoboard<FieldT>& pb,
2a2f3fb8 49 pb_variable<FieldT>& ZERO,
59c3d926
SB
50 std::shared_ptr<digest_variable<FieldT>> nullifier,
51 digest_variable<FieldT> rt
ca8d6c93
SB
52 ) : note_gadget<FieldT>(pb) {
53 a_sk.reset(new digest_variable<FieldT>(pb, 252, ""));
54 a_pk.reset(new digest_variable<FieldT>(pb, 256, ""));
2a2f3fb8 55 rho.reset(new digest_variable<FieldT>(pb, 256, ""));
fcece37f 56 commitment.reset(new digest_variable<FieldT>(pb, 256, ""));
2a2f3fb8 57
ca8d6c93
SB
58 spend_authority.reset(new PRF_addr_a_pk_gadget<FieldT>(
59 pb,
60 ZERO,
61 a_sk->bits,
62 a_pk
63 ));
2a2f3fb8
SB
64
65 expose_nullifiers.reset(new PRF_nf_gadget<FieldT>(
66 pb,
67 ZERO,
68 a_sk->bits,
69 rho->bits,
70 nullifier
71 ));
fcece37f
SB
72
73 commit_to_inputs.reset(new note_commitment_gadget<FieldT>(
74 pb,
75 ZERO,
76 a_pk->bits,
77 this->value,
78 rho->bits,
79 this->r->bits,
80 commitment
81 ));
59c3d926
SB
82
83 value_enforce.allocate(pb);
84
85 witness_input.reset(new merkle_tree_gadget<FieldT>(
86 pb,
87 *commitment,
88 rt,
89 value_enforce
90 ));
ca8d6c93
SB
91 }
92
93 void generate_r1cs_constraints() {
94 note_gadget<FieldT>::generate_r1cs_constraints();
95
96 a_sk->generate_r1cs_constraints();
2a2f3fb8 97 rho->generate_r1cs_constraints();
ca8d6c93 98
ca8d6c93 99 spend_authority->generate_r1cs_constraints();
2a2f3fb8 100 expose_nullifiers->generate_r1cs_constraints();
fcece37f
SB
101
102 commit_to_inputs->generate_r1cs_constraints();
59c3d926
SB
103
104 // value * (1 - enforce) = 0
105 // Given `enforce` is boolean constrained:
106 // If `value` is zero, `enforce` _can_ be zero.
107 // If `value` is nonzero, `enforce` _must_ be one.
108 generate_boolean_r1cs_constraint<FieldT>(this->pb, value_enforce,"");
109
110 this->pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
111 packed_addition(this->value),
112 (1 - value_enforce),
113 0
114 ), "");
115
116 witness_input->generate_r1cs_constraints();
ca8d6c93
SB
117 }
118
59c3d926
SB
119 void generate_r1cs_witness(
120 const MerklePath& path,
121 const SpendingKey& key,
b230fe68 122 const SproutNote& note
59c3d926 123 ) {
ca8d6c93
SB
124 note_gadget<FieldT>::generate_r1cs_witness(note);
125
126 // Witness a_sk for the input
127 a_sk->bits.fill_with_bits(
128 this->pb,
defe37a6 129 uint252_to_bool_vector(key)
ca8d6c93
SB
130 );
131
132 // Witness a_pk for a_sk with PRF_addr
133 spend_authority->generate_r1cs_witness();
134
135 // [SANITY CHECK] Witness a_pk with note information
136 a_pk->bits.fill_with_bits(
137 this->pb,
138 uint256_to_bool_vector(note.a_pk)
139 );
2a2f3fb8
SB
140
141 // Witness rho for the input note
142 rho->bits.fill_with_bits(
143 this->pb,
144 uint256_to_bool_vector(note.rho)
145 );
146
147 // Witness the nullifier for the input note
148 expose_nullifiers->generate_r1cs_witness();
fcece37f
SB
149
150 // Witness the commitment of the input note
151 commit_to_inputs->generate_r1cs_witness();
152
153 // [SANITY CHECK] Ensure the commitment is
154 // valid.
155 commitment->bits.fill_with_bits(
156 this->pb,
157 uint256_to_bool_vector(note.cm())
158 );
59c3d926
SB
159
160 // Set enforce flag for nonzero input value
5d99e3e9 161 this->pb.val(value_enforce) = (note.value() != 0) ? FieldT::one() : FieldT::zero();
59c3d926
SB
162
163 // Witness merkle tree authentication path
164 witness_input->generate_r1cs_witness(path);
ca8d6c93
SB
165 }
166};
6b010d9b
SB
167
168template<typename FieldT>
169class output_note_gadget : public note_gadget<FieldT> {
170private:
171 std::shared_ptr<digest_variable<FieldT>> rho;
5e61a78f 172 std::shared_ptr<digest_variable<FieldT>> a_pk;
6b010d9b
SB
173
174 std::shared_ptr<PRF_rho_gadget<FieldT>> prevent_faerie_gold;
5e61a78f 175 std::shared_ptr<note_commitment_gadget<FieldT>> commit_to_outputs;
6b010d9b
SB
176
177public:
178 output_note_gadget(
179 protoboard<FieldT>& pb,
180 pb_variable<FieldT>& ZERO,
181 pb_variable_array<FieldT>& phi,
182 pb_variable_array<FieldT>& h_sig,
5e61a78f
SB
183 bool nonce,
184 std::shared_ptr<digest_variable<FieldT>> commitment
6b010d9b
SB
185 ) : note_gadget<FieldT>(pb) {
186 rho.reset(new digest_variable<FieldT>(pb, 256, ""));
5e61a78f 187 a_pk.reset(new digest_variable<FieldT>(pb, 256, ""));
6b010d9b
SB
188
189 // Do not allow the caller to choose the same "rho"
190 // for any two valid notes in a given view of the
191 // blockchain. See protocol specification for more
192 // details.
193 prevent_faerie_gold.reset(new PRF_rho_gadget<FieldT>(
194 pb,
195 ZERO,
196 phi,
197 h_sig,
198 nonce,
199 rho
200 ));
5e61a78f
SB
201
202 // Commit to the output notes publicly without
203 // disclosing them.
204 commit_to_outputs.reset(new note_commitment_gadget<FieldT>(
205 pb,
206 ZERO,
207 a_pk->bits,
208 this->value,
209 rho->bits,
210 this->r->bits,
211 commitment
212 ));
6b010d9b
SB
213 }
214
215 void generate_r1cs_constraints() {
216 note_gadget<FieldT>::generate_r1cs_constraints();
217
5e61a78f
SB
218 a_pk->generate_r1cs_constraints();
219
6b010d9b 220 prevent_faerie_gold->generate_r1cs_constraints();
5e61a78f
SB
221
222 commit_to_outputs->generate_r1cs_constraints();
6b010d9b
SB
223 }
224
b230fe68 225 void generate_r1cs_witness(const SproutNote& note) {
6b010d9b
SB
226 note_gadget<FieldT>::generate_r1cs_witness(note);
227
228 prevent_faerie_gold->generate_r1cs_witness();
229
230 // [SANITY CHECK] Witness rho ourselves with the
231 // note information.
232 rho->bits.fill_with_bits(
233 this->pb,
234 uint256_to_bool_vector(note.rho)
235 );
5e61a78f
SB
236
237 a_pk->bits.fill_with_bits(
238 this->pb,
239 uint256_to_bool_vector(note.a_pk)
240 );
241
242 commit_to_outputs->generate_r1cs_witness();
6b010d9b
SB
243 }
244};
This page took 0.123236 seconds and 4 git commands to generate.