@@ -60,49 +60,6 @@ std::shared_ptr<ProverInstance_<Flavor>> _compute_prover_instance(std::vector<ui
6060
6161 return prover_instance;
6262}
63- template <typename Flavor, typename IO >
64- CircuitProve::Response _prove (std::vector<uint8_t >&& bytecode,
65- std::vector<uint8_t >&& witness,
66- std::vector<uint8_t >&& vk_bytes)
67- {
68- using Proof = typename Flavor::Transcript::Proof;
69- using VerificationKey = typename Flavor::VerificationKey;
70-
71- auto prover_instance = _compute_prover_instance<Flavor, IO >(std::move (bytecode), std::move (witness));
72-
73- // Create or deserialize VK
74- std::shared_ptr<VerificationKey> vk;
75- if (vk_bytes.empty ()) {
76- info (" WARNING: computing verification key while proving. Pass in a precomputed vk for better performance." );
77- vk = std::make_shared<VerificationKey>(prover_instance->get_precomputed ());
78- } else {
79- validate_vk_size<VerificationKey>(vk_bytes);
80- vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk_bytes));
81- }
82-
83- // Construct proof
84- UltraProver_<Flavor> prover{ prover_instance, vk };
85- Proof full_proof = prover.construct_proof ();
86-
87- // Compute where to split (inner public inputs vs everything else)
88- size_t num_public_inputs = prover.num_public_inputs ();
89- BB_ASSERT_GTE (num_public_inputs, IO ::PUBLIC_INPUTS_SIZE , " Public inputs should contain the expected IO structure." );
90- size_t num_inner_public_inputs = num_public_inputs - IO ::PUBLIC_INPUTS_SIZE ;
91-
92- // Optimization: if vk not provided, include it in response
93- CircuitComputeVk::Response vk_response;
94- if (vk_bytes.empty ()) {
95- vk_response = { .bytes = to_buffer (*vk), .fields = vk_to_uint256_fields (*vk), .hash = to_buffer (vk->hash ()) };
96- }
97-
98- // Split proof: inner public inputs at front, rest is the "proof"
99- return { .public_inputs =
100- std::vector<uint256_t >{ full_proof.begin (),
101- full_proof.begin () + static_cast <std::ptrdiff_t >(num_inner_public_inputs) },
102- .proof = std::vector<uint256_t >{ full_proof.begin () + static_cast <std::ptrdiff_t >(num_inner_public_inputs),
103- full_proof.end () },
104- .vk = std::move (vk_response) };
105- }
10663
10764template <typename Flavor, typename IO >
10865bool _verify (const std::vector<uint8_t >& vk_bytes,
@@ -145,6 +102,59 @@ bool _verify(const std::vector<uint8_t>& vk_bytes,
145102 return verified;
146103}
147104
105+ template <typename Flavor, typename IO >
106+ CircuitProve::Response _prove (std::vector<uint8_t >&& bytecode,
107+ std::vector<uint8_t >&& witness,
108+ std::vector<uint8_t >&& vk_bytes)
109+ {
110+ using Proof = typename Flavor::Transcript::Proof;
111+ using VerificationKey = typename Flavor::VerificationKey;
112+
113+ auto prover_instance = _compute_prover_instance<Flavor, IO >(std::move (bytecode), std::move (witness));
114+
115+ // Create or deserialize VK
116+ std::shared_ptr<VerificationKey> vk;
117+ if (vk_bytes.empty ()) {
118+ info (" WARNING: computing verification key while proving. Pass in a precomputed vk for better performance." );
119+ vk = std::make_shared<VerificationKey>(prover_instance->get_precomputed ());
120+ } else {
121+ validate_vk_size<VerificationKey>(vk_bytes);
122+ vk = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk_bytes));
123+ }
124+
125+ // Construct proof
126+ UltraProver_<Flavor> prover{ prover_instance, vk };
127+ Proof full_proof = prover.construct_proof ();
128+
129+ // Compute where to split (inner public inputs vs everything else)
130+ size_t num_public_inputs = prover.num_public_inputs ();
131+ BB_ASSERT_GTE (num_public_inputs, IO ::PUBLIC_INPUTS_SIZE , " Public inputs should contain the expected IO structure." );
132+ size_t num_inner_public_inputs = num_public_inputs - IO ::PUBLIC_INPUTS_SIZE ;
133+
134+ // Optimization: if vk not provided, include it in response
135+ CircuitComputeVk::Response vk_response;
136+ if (vk_bytes.empty ()) {
137+ vk_response = { .bytes = to_buffer (*vk), .fields = vk_to_uint256_fields (*vk), .hash = to_buffer (vk->hash ()) };
138+ }
139+
140+ // Split proof: inner public inputs at front, rest is the "proof"
141+ CircuitProve::Response response{
142+ .public_inputs =
143+ std::vector<uint256_t >{ full_proof.begin (),
144+ full_proof.begin () + static_cast <std::ptrdiff_t >(num_inner_public_inputs) },
145+ .proof = std::vector<uint256_t >{ full_proof.begin () + static_cast <std::ptrdiff_t >(num_inner_public_inputs),
146+ full_proof.end () },
147+ .vk = std::move (vk_response)
148+ };
149+
150+ // Sanity-check the generated proof
151+ if (!_verify<Flavor, IO >(to_buffer (*vk), response.public_inputs , response.proof )) {
152+ throw_or_abort (" Failed to verify the generated proof!" );
153+ }
154+
155+ return response;
156+ }
157+
148158CircuitProve::Response CircuitProve::execute (BB_UNUSED const BBApiRequest& request) &&
149159{
150160 BB_BENCH_NAME (MSGPACK_SCHEMA_NAME );
0 commit comments