2 *****************************************************************************
4 Implementation of functionality for creating and using the two PCD circuits in
5 a single-predicate PCD construction.
7 See sp_pcd_circuits.hpp .
9 *****************************************************************************
10 * @author This file is part of libsnark, developed by SCIPR Lab
11 * and contributors (see AUTHORS).
12 * @copyright MIT license (see LICENSE file)
13 *****************************************************************************/
15 #ifndef SP_PCD_CIRCUITS_TCC_
16 #define SP_PCD_CIRCUITS_TCC_
18 #include <libff/common/utils.hpp>
19 #include <libsnark/gadgetlib1/constraint_profiling.hpp>
24 template<typename ppT>
25 sp_compliance_step_pcd_circuit_maker<ppT>::sp_compliance_step_pcd_circuit_maker(
26 const r1cs_pcd_compliance_predicate<FieldT> &compliance_predicate)
27 : compliance_predicate(compliance_predicate)
29 /* calculate some useful sizes */
30 assert(compliance_predicate.is_well_formed());
31 assert(compliance_predicate.has_equal_input_and_output_lengths());
33 const size_t compliance_predicate_arity = compliance_predicate.max_arity;
34 const size_t digest_size =
35 CRH_with_field_out_gadget<FieldT>::get_digest_len();
36 const size_t msg_size_in_bits =
38 (1 + compliance_predicate.outgoing_message_payload_length);
39 const size_t sp_translation_step_vk_size_in_bits =
40 r1cs_ppzksnark_verification_key_variable<ppT>::size_in_bits(
41 sp_translation_step_pcd_circuit_maker<
42 other_curve<ppT>>::input_size_in_elts());
43 const size_t padded_verifier_input_size =
44 sp_translation_step_pcd_circuit_maker<
45 other_curve<ppT>>::input_capacity_in_bits();
48 "other curve input size = %zu\n",
49 sp_translation_step_pcd_circuit_maker<
50 other_curve<ppT>>::input_size_in_elts());
51 printf("translation_vk_bits = %zu\n", sp_translation_step_vk_size_in_bits);
52 printf("padded verifier input size = %zu\n", padded_verifier_input_size);
54 const size_t block_size =
55 msg_size_in_bits + sp_translation_step_vk_size_in_bits;
56 CRH_with_bit_out_gadget<FieldT>::sample_randomness(block_size);
58 /* allocate input of the compliance PCD circuit */
59 sp_compliance_step_pcd_circuit_input.allocate(
60 pb, input_size_in_elts(), "sp_compliance_step_pcd_circuit_input");
62 /* allocate inputs to the compliance predicate */
63 outgoing_message_type.allocate(pb, "outgoing_message_type");
64 outgoing_message_payload.allocate(
66 compliance_predicate.outgoing_message_payload_length,
67 "outgoing_message_payload");
69 outgoing_message_vars.insert(
70 outgoing_message_vars.end(), outgoing_message_type);
71 outgoing_message_vars.insert(
72 outgoing_message_vars.end(),
73 outgoing_message_payload.begin(),
74 outgoing_message_payload.end());
76 arity.allocate(pb, "arity");
78 incoming_message_types.resize(compliance_predicate_arity);
79 incoming_message_payloads.resize(compliance_predicate_arity);
80 incoming_message_vars.resize(compliance_predicate_arity);
81 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
82 incoming_message_types[i].allocate(
83 pb, FMT("", "incoming_message_type_%zu", i));
84 incoming_message_payloads[i].allocate(
86 compliance_predicate.outgoing_message_payload_length,
87 FMT("", "incoming_message_payloads_%zu", i));
89 incoming_message_vars[i].insert(
90 incoming_message_vars[i].end(), incoming_message_types[i]);
91 incoming_message_vars[i].insert(
92 incoming_message_vars[i].end(),
93 incoming_message_payloads[i].begin(),
94 incoming_message_payloads[i].end());
98 pb, compliance_predicate.local_data_length, "local_data");
99 cp_witness.allocate(pb, compliance_predicate.witness_length, "cp_witness");
101 /* convert compliance predicate from a constraint system into a gadget */
102 pb_variable_array<FieldT> incoming_messages_concat;
103 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
104 incoming_messages_concat.insert(
105 incoming_messages_concat.end(),
106 incoming_message_vars[i].begin(),
107 incoming_message_vars[i].end());
110 compliance_predicate_as_gadget.reset(new gadget_from_r1cs<FieldT>(
112 {outgoing_message_vars,
113 pb_variable_array<FieldT>(1, arity),
114 incoming_messages_concat,
117 compliance_predicate.constraint_system,
118 "compliance_predicate_as_gadget"));
120 /* unpack messages to bits */
121 outgoing_message_bits.allocate(
122 pb, msg_size_in_bits, "outgoing_message_bits");
123 unpack_outgoing_message.reset(new multipacking_gadget<FieldT>(
125 outgoing_message_bits,
126 outgoing_message_vars,
128 "unpack_outgoing_message"));
130 incoming_messages_bits.resize(compliance_predicate_arity);
131 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
132 incoming_messages_bits[i].allocate(
133 pb, msg_size_in_bits, FMT("", "incoming_messages_bits_%zu", i));
134 unpack_incoming_messages.emplace_back(multipacking_gadget<FieldT>(
136 incoming_messages_bits[i],
137 incoming_message_vars[i],
139 FMT("", "unpack_incoming_messages_%zu", i)));
142 /* allocate digests */
143 sp_translation_step_vk_and_incoming_message_payload_digests.resize(
144 compliance_predicate_arity);
145 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
146 sp_translation_step_vk_and_incoming_message_payload_digests[i].allocate(
150 "sp_translation_step_vk_and_incoming_message_payload_digests_%"
155 /* allocate blocks */
156 sp_translation_step_vk_bits.allocate(
157 pb, sp_translation_step_vk_size_in_bits, "sp_translation_step_vk_bits");
159 block_for_outgoing_message.reset(new block_variable<FieldT>(
161 {sp_translation_step_vk_bits, outgoing_message_bits},
162 "block_for_outgoing_message"));
164 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
165 blocks_for_incoming_messages.emplace_back(block_variable<FieldT>(
167 {sp_translation_step_vk_bits, incoming_messages_bits[i]},
168 FMT("", "blocks_for_incoming_messages_zu", i)));
171 /* allocate hash checkers */
172 hash_outgoing_message.reset(new CRH_with_field_out_gadget<FieldT>(
175 *block_for_outgoing_message,
176 sp_compliance_step_pcd_circuit_input,
177 "hash_outgoing_message"));
179 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
180 hash_incoming_messages.emplace_back(CRH_with_field_out_gadget<FieldT>(
183 blocks_for_incoming_messages[i],
184 sp_translation_step_vk_and_incoming_message_payload_digests[i],
185 FMT("", "hash_incoming_messages_%zu", i)));
188 /* allocate useful zero variable */
189 zero.allocate(pb, "zero");
191 /* prepare arguments for the verifier */
192 sp_translation_step_vk.reset(
193 new r1cs_ppzksnark_verification_key_variable<ppT>(
195 sp_translation_step_vk_bits,
196 sp_translation_step_pcd_circuit_maker<
197 other_curve<ppT>>::input_size_in_elts(),
198 "sp_translation_step_vk"));
200 verification_result.allocate(pb, "verification_result");
201 sp_translation_step_vk_and_incoming_message_payload_digest_bits.resize(
202 compliance_predicate_arity);
204 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
205 sp_translation_step_vk_and_incoming_message_payload_digest_bits[i]
208 digest_size * field_logsize(),
210 "sp_translation_step_vk_and_incoming_message_payload_"
213 unpack_sp_translation_step_vk_and_incoming_message_payload_digests
214 .emplace_back(multipacking_gadget<FieldT>(
216 sp_translation_step_vk_and_incoming_message_payload_digest_bits
218 sp_translation_step_vk_and_incoming_message_payload_digests[i],
221 "unpack_sp_translation_step_vk_and_incoming_message_"
222 "payload_digests_%zu",
225 verifier_input.emplace_back(
226 sp_translation_step_vk_and_incoming_message_payload_digest_bits[i]);
227 while (verifier_input[i].size() < padded_verifier_input_size) {
228 verifier_input[i].emplace_back(zero);
232 r1cs_ppzksnark_proof_variable<ppT>(pb, FMT("", "proof_%zu", i)));
233 verifiers.emplace_back(r1cs_ppzksnark_verifier_gadget<ppT>(
235 *sp_translation_step_vk,
237 sp_translation_step_pcd_circuit_maker<
238 other_curve<ppT>>::field_capacity(),
241 FMT("", "verifiers_%zu", i)));
244 pb.set_input_sizes(input_size_in_elts());
245 printf("done compliance\n");
248 template<typename ppT>
249 void sp_compliance_step_pcd_circuit_maker<ppT>::generate_r1cs_constraints()
251 const size_t digest_size =
252 CRH_with_bit_out_gadget<FieldT>::get_digest_len();
253 const size_t dimension = knapsack_dimension<FieldT>::dimension;
254 libff::print_indent();
255 printf("* Knapsack dimension: %zu\n", dimension);
257 const size_t compliance_predicate_arity = compliance_predicate.max_arity;
258 libff::print_indent();
259 printf("* Compliance predicate arity: %zu\n", compliance_predicate_arity);
260 libff::print_indent();
262 "* Compliance predicate payload length: %zu\n",
263 compliance_predicate.outgoing_message_payload_length);
264 libff::print_indent();
266 "* Compliance predicate local data length: %zu\n",
267 compliance_predicate.local_data_length);
268 libff::print_indent();
270 "* Compliance predicate witness length: %zu\n",
271 compliance_predicate.witness_length);
273 PROFILE_CONSTRAINTS(pb, "booleanity")
275 PROFILE_CONSTRAINTS(pb, "booleanity: unpack outgoing_message")
277 unpack_outgoing_message->generate_r1cs_constraints(true);
280 PROFILE_CONSTRAINTS(pb, "booleanity: unpack s incoming_message")
282 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
283 unpack_incoming_messages[i].generate_r1cs_constraints(true);
287 PROFILE_CONSTRAINTS(pb, "booleanity: unpack verification key")
289 sp_translation_step_vk->generate_r1cs_constraints(true);
293 PROFILE_CONSTRAINTS(pb, "(1+s) copies of hash")
295 libff::print_indent();
296 printf("* Digest-size: %zu\n", digest_size);
297 hash_outgoing_message->generate_r1cs_constraints();
299 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
300 hash_incoming_messages[i].generate_r1cs_constraints();
304 PROFILE_CONSTRAINTS(pb, "s copies of repacking circuit")
306 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
307 unpack_sp_translation_step_vk_and_incoming_message_payload_digests
309 .generate_r1cs_constraints(true);
313 PROFILE_CONSTRAINTS(pb, "compliance predicate")
315 compliance_predicate_as_gadget->generate_r1cs_constraints();
318 PROFILE_CONSTRAINTS(pb, "s copies of verifier for translated proofs")
320 PROFILE_CONSTRAINTS(pb, "check that s proofs lie on the curve")
322 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
323 proof[i].generate_r1cs_constraints();
327 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
328 verifiers[i].generate_r1cs_constraints();
332 PROFILE_CONSTRAINTS(pb, "miscellaneous")
334 generate_r1cs_equals_const_constraint<FieldT>(
335 pb, zero, FieldT::zero(), "zero");
336 generate_boolean_r1cs_constraint<FieldT>(
337 pb, verification_result, "verification_result");
339 /* type * (1-verification_result) = 0 */
340 pb.add_r1cs_constraint(
341 r1cs_constraint<FieldT>(
342 incoming_message_types[0], 1 - verification_result, 0),
343 "not_base_case_implies_valid_proofs");
345 /* all types equal */
346 for (size_t i = 1; i < compliance_predicate.max_arity; ++i) {
347 pb.add_r1cs_constraint(
348 r1cs_constraint<FieldT>(
349 1, incoming_message_types[0], incoming_message_types[i]),
350 FMT("", "type_%zu_equal_to_type_0", i));
353 pb.add_r1cs_constraint(
354 r1cs_constraint<FieldT>(1, arity, compliance_predicate_arity),
356 pb.add_r1cs_constraint(
357 r1cs_constraint<FieldT>(
358 1, outgoing_message_type, FieldT(compliance_predicate.type)),
359 "enforce_outgoing_type");
362 PRINT_CONSTRAINT_PROFILING();
363 libff::print_indent();
365 "* Number of constraints in sp_compliance_step_pcd_circuit: %zu\n",
366 pb.num_constraints());
369 template<typename ppT>
370 r1cs_constraint_system<libff::Fr<ppT>> sp_compliance_step_pcd_circuit_maker<
371 ppT>::get_circuit() const
373 return pb.get_constraint_system();
376 template<typename ppT>
377 r1cs_primary_input<libff::Fr<ppT>> sp_compliance_step_pcd_circuit_maker<
378 ppT>::get_primary_input() const
380 return pb.primary_input();
383 template<typename ppT>
384 r1cs_auxiliary_input<libff::Fr<ppT>> sp_compliance_step_pcd_circuit_maker<
385 ppT>::get_auxiliary_input() const
387 return pb.auxiliary_input();
390 template<typename ppT>
391 void sp_compliance_step_pcd_circuit_maker<ppT>::generate_r1cs_witness(
392 const r1cs_ppzksnark_verification_key<other_curve<ppT>>
393 &sp_translation_step_pcd_circuit_vk,
394 const r1cs_pcd_compliance_predicate_primary_input<FieldT>
395 &compliance_predicate_primary_input,
396 const r1cs_pcd_compliance_predicate_auxiliary_input<FieldT>
397 &compliance_predicate_auxiliary_input,
398 const std::vector<r1cs_ppzksnark_proof<other_curve<ppT>>> &incoming_proofs)
400 const size_t compliance_predicate_arity = compliance_predicate.max_arity;
401 this->pb.clear_values();
402 this->pb.val(zero) = FieldT::zero();
404 compliance_predicate_as_gadget->generate_r1cs_witness(
405 compliance_predicate_primary_input.as_r1cs_primary_input(),
406 compliance_predicate_auxiliary_input.as_r1cs_auxiliary_input(
407 compliance_predicate.incoming_message_payload_lengths));
408 this->pb.val(arity) = FieldT(compliance_predicate_arity);
409 unpack_outgoing_message->generate_r1cs_witness_from_packed();
410 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
411 unpack_incoming_messages[i].generate_r1cs_witness_from_packed();
414 sp_translation_step_vk->generate_r1cs_witness(
415 sp_translation_step_pcd_circuit_vk);
416 hash_outgoing_message->generate_r1cs_witness();
417 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
418 hash_incoming_messages[i].generate_r1cs_witness();
419 unpack_sp_translation_step_vk_and_incoming_message_payload_digests[i]
420 .generate_r1cs_witness_from_packed();
423 for (size_t i = 0; i < compliance_predicate_arity; ++i) {
424 proof[i].generate_r1cs_witness(incoming_proofs[i]);
425 verifiers[i].generate_r1cs_witness();
428 if (this->pb.val(incoming_message_types[0]) != FieldT::zero()) {
429 this->pb.val(verification_result) = FieldT::one();
433 generate_r1cs_constraints(); // force generating constraints
434 assert(this->pb.is_satisfied());
438 template<typename ppT>
439 size_t sp_compliance_step_pcd_circuit_maker<ppT>::field_logsize()
441 return libff::Fr<ppT>::size_in_bits();
444 template<typename ppT>
445 size_t sp_compliance_step_pcd_circuit_maker<ppT>::field_capacity()
447 return libff::Fr<ppT>::capacity();
450 template<typename ppT>
451 size_t sp_compliance_step_pcd_circuit_maker<ppT>::input_size_in_elts()
453 const size_t digest_size =
454 CRH_with_field_out_gadget<FieldT>::get_digest_len();
458 template<typename ppT>
459 size_t sp_compliance_step_pcd_circuit_maker<ppT>::input_capacity_in_bits()
461 return input_size_in_elts() * field_capacity();
464 template<typename ppT>
465 size_t sp_compliance_step_pcd_circuit_maker<ppT>::input_size_in_bits()
467 return input_size_in_elts() * field_logsize();
470 template<typename ppT>
471 sp_translation_step_pcd_circuit_maker<ppT>::
472 sp_translation_step_pcd_circuit_maker(
473 const r1cs_ppzksnark_verification_key<other_curve<ppT>>
474 &sp_compliance_step_vk)
476 /* allocate input of the translation PCD circuit */
477 sp_translation_step_pcd_circuit_input.allocate(
478 pb, input_size_in_elts(), "sp_translation_step_pcd_circuit_input");
480 /* unpack translation step PCD circuit input */
481 unpacked_sp_translation_step_pcd_circuit_input.allocate(
483 sp_compliance_step_pcd_circuit_maker<
484 other_curve<ppT>>::input_size_in_bits(),
485 "unpacked_sp_translation_step_pcd_circuit_input");
486 unpack_sp_translation_step_pcd_circuit_input.reset(
487 new multipacking_gadget<FieldT>(
489 unpacked_sp_translation_step_pcd_circuit_input,
490 sp_translation_step_pcd_circuit_input,
492 "unpack_sp_translation_step_pcd_circuit_input"));
494 /* prepare arguments for the verifier */
495 hardcoded_sp_compliance_step_vk.reset(
496 new r1cs_ppzksnark_preprocessed_r1cs_ppzksnark_verification_key_variable<
497 ppT>(pb, sp_compliance_step_vk, "hardcoded_sp_compliance_step_vk"));
498 proof.reset(new r1cs_ppzksnark_proof_variable<ppT>(pb, "proof"));
500 /* verify previous proof */
501 online_verifier.reset(new r1cs_ppzksnark_online_verifier_gadget<ppT>(
503 *hardcoded_sp_compliance_step_vk,
504 unpacked_sp_translation_step_pcd_circuit_input,
505 sp_compliance_step_pcd_circuit_maker<other_curve<ppT>>::field_logsize(),
507 ONE, // must always accept
509 pb.set_input_sizes(input_size_in_elts());
511 printf("done translation\n");
514 template<typename ppT>
515 void sp_translation_step_pcd_circuit_maker<ppT>::generate_r1cs_constraints()
517 PROFILE_CONSTRAINTS(pb, "repacking: unpack circuit input")
519 unpack_sp_translation_step_pcd_circuit_input->generate_r1cs_constraints(
523 PROFILE_CONSTRAINTS(pb, "verifier for compliance proofs")
525 PROFILE_CONSTRAINTS(pb, "check that proof lies on the curve")
527 proof->generate_r1cs_constraints();
530 online_verifier->generate_r1cs_constraints();
533 PRINT_CONSTRAINT_PROFILING();
534 libff::print_indent();
536 "* Number of constraints in sp_translation_step_pcd_circuit: %zu\n",
537 pb.num_constraints());
540 template<typename ppT>
541 r1cs_constraint_system<libff::Fr<ppT>> sp_translation_step_pcd_circuit_maker<
542 ppT>::get_circuit() const
544 return pb.get_constraint_system();
547 template<typename ppT>
548 void sp_translation_step_pcd_circuit_maker<ppT>::generate_r1cs_witness(
549 const r1cs_primary_input<libff::Fr<ppT>> sp_translation_step_input,
550 const r1cs_ppzksnark_proof<other_curve<ppT>> &compliance_step_proof)
552 this->pb.clear_values();
553 sp_translation_step_pcd_circuit_input.fill_with_field_elements(
554 pb, sp_translation_step_input);
555 unpack_sp_translation_step_pcd_circuit_input
556 ->generate_r1cs_witness_from_packed();
558 proof->generate_r1cs_witness(compliance_step_proof);
559 online_verifier->generate_r1cs_witness();
562 generate_r1cs_constraints(); // force generating constraints
564 printf("Input to the translation circuit:\n");
565 for (size_t i = 0; i < this->pb.num_inputs(); ++i) {
566 this->pb.val(pb_variable<FieldT>(i + 1)).print();
569 assert(this->pb.is_satisfied());
573 template<typename ppT>
574 r1cs_primary_input<libff::Fr<ppT>> sp_translation_step_pcd_circuit_maker<
575 ppT>::get_primary_input() const
577 return pb.primary_input();
580 template<typename ppT>
581 r1cs_auxiliary_input<libff::Fr<ppT>> sp_translation_step_pcd_circuit_maker<
582 ppT>::get_auxiliary_input() const
584 return pb.auxiliary_input();
587 template<typename ppT>
588 size_t sp_translation_step_pcd_circuit_maker<ppT>::field_logsize()
590 return libff::Fr<ppT>::size_in_bits();
593 template<typename ppT>
594 size_t sp_translation_step_pcd_circuit_maker<ppT>::field_capacity()
596 return libff::Fr<ppT>::capacity();
599 template<typename ppT>
600 size_t sp_translation_step_pcd_circuit_maker<ppT>::input_size_in_elts()
602 return libff::div_ceil(
603 sp_compliance_step_pcd_circuit_maker<
604 other_curve<ppT>>::input_size_in_bits(),
605 sp_translation_step_pcd_circuit_maker<ppT>::field_capacity());
608 template<typename ppT>
609 size_t sp_translation_step_pcd_circuit_maker<ppT>::input_capacity_in_bits()
611 return input_size_in_elts() * field_capacity();
614 template<typename ppT>
615 size_t sp_translation_step_pcd_circuit_maker<ppT>::input_size_in_bits()
617 return input_size_in_elts() * field_logsize();
620 template<typename ppT>
621 r1cs_primary_input<libff::Fr<ppT>> get_sp_compliance_step_pcd_circuit_input(
622 const libff::bit_vector &sp_translation_step_vk_bits,
623 const r1cs_pcd_compliance_predicate_primary_input<libff::Fr<ppT>>
626 libff::enter_block("Call to get_sp_compliance_step_pcd_circuit_input");
627 typedef libff::Fr<ppT> FieldT;
629 const r1cs_variable_assignment<FieldT> outgoing_message_as_va =
630 primary_input.outgoing_message->as_r1cs_variable_assignment();
631 libff::bit_vector msg_bits;
632 for (const FieldT &elt : outgoing_message_as_va) {
633 const libff::bit_vector elt_bits =
634 libff::convert_field_element_to_bit_vector(elt);
635 msg_bits.insert(msg_bits.end(), elt_bits.begin(), elt_bits.end());
638 libff::bit_vector block;
641 sp_translation_step_vk_bits.begin(),
642 sp_translation_step_vk_bits.end());
643 block.insert(block.end(), msg_bits.begin(), msg_bits.end());
645 libff::enter_block("Sample CRH randomness");
646 CRH_with_field_out_gadget<FieldT>::sample_randomness(block.size());
647 libff::leave_block("Sample CRH randomness");
649 const std::vector<FieldT> digest =
650 CRH_with_field_out_gadget<FieldT>::get_hash(block);
651 libff::leave_block("Call to get_sp_compliance_step_pcd_circuit_input");
656 template<typename ppT>
657 r1cs_primary_input<libff::Fr<ppT>> get_sp_translation_step_pcd_circuit_input(
658 const libff::bit_vector &sp_translation_step_vk_bits,
659 const r1cs_pcd_compliance_predicate_primary_input<
660 libff::Fr<other_curve<ppT>>> &primary_input)
662 libff::enter_block("Call to get_sp_translation_step_pcd_circuit_input");
663 typedef libff::Fr<ppT> FieldT;
665 const std::vector<libff::Fr<other_curve<ppT>>>
666 sp_compliance_step_pcd_circuit_input =
667 get_sp_compliance_step_pcd_circuit_input<other_curve<ppT>>(
668 sp_translation_step_vk_bits, primary_input);
669 libff::bit_vector sp_compliance_step_pcd_circuit_input_bits;
670 for (const libff::Fr<other_curve<ppT>> &elt :
671 sp_compliance_step_pcd_circuit_input) {
672 const libff::bit_vector elt_bits =
673 libff::convert_field_element_to_bit_vector<
674 libff::Fr<other_curve<ppT>>>(elt);
675 sp_compliance_step_pcd_circuit_input_bits.insert(
676 sp_compliance_step_pcd_circuit_input_bits.end(),
681 sp_compliance_step_pcd_circuit_input_bits.resize(
682 sp_translation_step_pcd_circuit_maker<ppT>::input_capacity_in_bits(),
685 const r1cs_primary_input<FieldT> result =
686 libff::pack_bit_vector_into_field_element_vector<FieldT>(
687 sp_compliance_step_pcd_circuit_input_bits,
688 sp_translation_step_pcd_circuit_maker<ppT>::field_capacity());
689 libff::leave_block("Call to get_sp_translation_step_pcd_circuit_input");
694 } // namespace libsnark
696 #endif // SP_PCD_CIRCUITS_TCC_