39 LigeroTranscript<Field>::write_commitment(commitment, ts);
47 const LigeroHash& hash_of_llterm,
const Elt b[],
49 const InterpolatorFactory& interpolator,
const Field& F) {
54 std::vector<Elt> u_ldt(p.nwqrow);
55 std::vector<Elt> alphal(nl);
56 std::vector<std::array<Elt, 3>> alphaq(p.nq);
57 std::vector<Elt> u_quad(p.nqtriples);
58 std::vector<size_t> idx(p.nreq);
65 ts.write(hash_of_llterm.bytes, hash_of_llterm.kLength);
68 LigeroTranscript<Field>::gen_uldt(&u_ldt[0], p, ts, F);
71 LigeroTranscript<Field>::gen_alphal(nl, &alphal[0], ts, F);
72 LigeroTranscript<Field>::gen_alphaq(&alphaq[0], p, ts, F);
75 LigeroTranscript<Field>::gen_uquad(&u_quad[0], p, ts, F);
78 ts.write(&proof.y_ldt[0], 1, p.block, F);
79 ts.write(&proof.y_dot[0], 1, p.dblock, F);
80 ts.write(&proof.y_quad_0[0], 1, p.r, F);
81 ts.write(&proof.y_quad_2[0], 1, p.dblock - p.block, F);
84 LigeroTranscript<Field>::gen_idx(&idx[0], p, ts, F);
86 if (!merkle_check(p, commitment, proof, &idx[0], F)) {
87 *why =
"merkle_check failed";
91 if (!low_degree_check(p, proof, &idx[0], &u_ldt[0], interpolator, F)) {
92 *why =
"low_degree_check failed";
98 std::vector<Elt> A(p.nwqrow * p.w);
100 LigeroCommon<Field>::inner_product_vector(&A[0], p, nl, nllterm, llterm,
101 &alphal[0], lqc, &alphaq[0], F);
103 if (!dot_check(p, proof, &idx[0], &A[0], interpolator, F)) {
104 *why =
"dot_check failed";
109 Elt want_dot = Blas<Field>::dot(nl, b, 1, &alphal[0], 1, F);
110 Elt proof_dot = Blas<Field>::dot1(p.w, &proof.y_dot[p.r], 1, F);
111 if (want_dot != proof_dot) {
112 *why =
"wrong dot product";
117 if (!quadratic_check(p, proof, &idx[0], &u_quad[0], interpolator, F)) {
118 *why =
"quadratic_check failed";
127 static void interpolate_req_columns(Elt yp[],
131 const InterpolatorFactory& interpolator,
133 const auto interpy = interpolator.make(ylen, p.block_enc);
134 std::vector<Elt> yext(p.block_enc);
135 Blas<Field>::copy(ylen, &yext[0], 1, y, 1);
136 interpy->interpolate(&yext[0]);
137 Blas<Field>::gather(p.nreq, &yp[0], &yext[p.dblock], idx);
143 const size_t idx[],
const Field& F) {
144 auto updhash = [&](
size_t r,
SHA256& sha) {
145 LigeroCommon<Field>::column_hash(p.nrow, &proof.req_at(0, r), p.nreq, sha,
149 return MerkleCommitmentVerifier::verify(p.block_enc - p.dblock,
150 commitment.root, proof.merkle, idx,
158 const InterpolatorFactory& interpolator,
160 std::vector<Elt> yc(p.nreq);
163 Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.ildt, 0), 1);
166 for (
size_t i = 0; i < p.nwqrow; ++i) {
167 Blas<Field>::axpy(p.nreq, &yc[0], 1, u_ldt[i], &proof.req_at(i + p.iw, 0),
171 std::vector<Elt> yp(p.nreq);
172 interpolate_req_columns(&yp[0], p, p.block, &proof.y_ldt[0], idx,
175 if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {
184 const size_t idx[],
const Elt A[],
185 const InterpolatorFactory& interpolator,
187 std::vector<Elt> yc(p.nreq);
190 Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.idot, 0), 1);
193 const auto interpA = interpolator.make(p.block, p.block_enc);
195 std::vector<Elt> Aext(p.block_enc);
196 std::vector<Elt> Areq(p.nreq);
198 for (
size_t i = 0; i < p.nwqrow; ++i) {
199 LigeroCommon<Field>::layout_Aext(&Aext[0], p, i, &A[0], F);
200 interpA->interpolate(&Aext[0]);
201 Blas<Field>::gather(p.nreq, &Areq[0], &Aext[p.dblock], idx);
204 Blas<Field>::vaxpy(p.nreq, &yc[0], 1, &Areq[0], 1,
205 &proof.req_at(i + p.iw, 0), 1, F);
209 std::vector<Elt> yp(p.nreq);
210 interpolate_req_columns(&yp[0], p, p.dblock, &proof.y_dot[0], idx,
213 if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {
223 const InterpolatorFactory& interpolator,
225 std::vector<Elt> yc(p.nreq);
228 Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.iquad, 0), 1);
231 std::vector<Elt> tmp(p.nreq);
233 size_t iqy = iqx + p.nqtriples;
234 size_t iqz = iqy + p.nqtriples;
237 for (
size_t i = 0; i < p.nqtriples; ++i) {
241 Blas<Field>::copy(p.nreq, &tmp[0], 1, &proof.req_at(iqz + i, 0), 1);
244 Blas<Field>::vymax(p.nreq, &tmp[0], 1, &proof.req_at(iqx + i, 0), 1,
245 &proof.req_at(iqy + i, 0), 1, F);
248 Blas<Field>::axpy(p.nreq, &yc[0], 1, u_quad[i], &tmp[0], 1, F);
253 std::vector<Elt> yquad(p.dblock);
254 Blas<Field>::copy(p.r, &yquad[0], 1, &proof.y_quad_0[0], 1);
255 Blas<Field>::clear(p.w, &yquad[p.r], 1, F);
256 Blas<Field>::copy(p.dblock - p.block, &yquad[p.block], 1,
257 &proof.y_quad_2[0], 1);
260 std::vector<Elt> yp(p.nreq);
261 interpolate_req_columns(&yp[0], p, p.dblock, &yquad[0], idx, interpolator,
264 if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {