148 LigeroParam(
size_t nw,
size_t nq,
size_t rateinv,
size_t nreq)
149 : nw(nw), nq(nq), rateinv(rateinv), nreq(nreq) {
152 size_t min_proof_size = SIZE_MAX;
153 size_t best_block_enc = 1;
154 for (
size_t e = 1; e <= (1 << 28); e *= 2) {
155 size_t proof_size = layout(e);
156 if (proof_size < min_proof_size) {
157 min_proof_size = proof_size;
163 layout(best_block_enc);
164 proofs::check(block_enc > block,
"block_enc > block");
171 proofs::check(nrow == iq + 3 * nqtriples,
"nrow == iq + 3 * nqtriples");
180 size_t layout(
size_t e) {
187 constexpr size_t max_lg_size = 28;
188 constexpr size_t max_size =
static_cast<size_t>(1) << max_lg_size;
192 size_t subfield_bits = 8 * Field::kSubFieldBytes;
193 if (subfield_bits <= max_lg_size) {
194 if (block_enc >= (
static_cast<size_t>(1) << subfield_bits)) {
201 if (block_enc > max_size || rateinv > max_size ||
202 (block_enc + 1) < (2 + rateinv)) {
206 block = (block_enc + 1) / (2 + rateinv);
228 dblock = 2 * block - 1;
233 if (block_enc < dblock) {
238 block_ext = block_enc - dblock;
241 nwrow = ceildiv(nw, w);
242 nqtriples = ceildiv(nq, w);
244 nwqrow = nwrow + 3 * nqtriples;
249 if (nrow >= max_size / block_enc) {
253 mc_pathlen = merkle_commitment_len(block_ext);
265 sz +=
static_cast<uint64_t
>(mc_pathlen) / 2 *
static_cast<uint64_t
>(nreq) *
266 static_cast<uint64_t
>(Digest::kLength);
269 sz +=
static_cast<uint64_t
>(block) *
static_cast<uint64_t
>(Field::kBytes);
272 sz +=
static_cast<uint64_t
>(dblock) *
static_cast<uint64_t
>(Field::kBytes);
277 sz +=
static_cast<uint64_t
>(dblock - w) *
278 static_cast<uint64_t
>(Field::kBytes);
281 sz +=
static_cast<uint64_t
>(nreq) *
282 static_cast<uint64_t
>(MerkleNonce::kLength);
285 sz +=
static_cast<uint64_t
>(nrow) *
static_cast<uint64_t
>(nreq) *
286 static_cast<uint64_t
>(Field::kSubFieldBytes);
288 sz = std::min<uint64_t>(sz, SIZE_MAX);
289 return static_cast<size_t>(sz);
305 block_enc(p->block_enc),
308 mc_pathlen(p->mc_pathlen),
312 y_quad_2(p->dblock - p->block),
313 req(p->nrow * p->nreq),
325 std::vector<Elt> y_ldt;
326 std::vector<Elt> y_dot;
327 std::vector<Elt> y_quad_0;
329 std::vector<Elt> y_quad_2;
330 std::vector<Elt> req;
333 Elt &req_at(
size_t i,
size_t j) {
return req[i * nreq + j]; }
334 const Elt &req_at(
size_t i,
size_t j)
const {
return req[i * nreq + j]; }
366 static void inner_product_vector(
370 const std::array<Elt, 3> alphaq[],
const Field &F) {
372 Blas<Field>::clear(p.nwqrow * p.w, A, 1, F);
375 for (
size_t l = 0; l < nllterm; ++l) {
376 const auto &
term = llterm[l];
377 proofs::check(
term.w < p.nw,
"term.w < p.nw");
378 proofs::check(
term.c < nl,
"term.c < nl");
383 Elt *Ax = &A[p.nwrow * p.w];
384 Elt *Ay = Ax + (p.nqtriples * p.w);
385 Elt *Az = Ay + (p.nqtriples * p.w);
387 for (
size_t i = 0; i < p.nqtriples; ++i) {
388 for (
size_t j = 0; j < p.w && j + i * p.w < p.nq; ++j) {
390 size_t iw = j + i * p.w;
391 const auto *l = &lqc[iw];
392 F.add(Ax[iw], alphaq[iw][0]);
393 F.sub(A[l->x], alphaq[iw][0]);
395 F.add(Ay[iw], alphaq[iw][1]);
396 F.sub(A[l->y], alphaq[iw][1]);
398 F.add(Az[iw], alphaq[iw][2]);
399 F.sub(A[l->z], alphaq[iw][2]);
407 size_t i,
const Elt A[],
409 Blas<Field>::clear(p.r, &Aext[0], 1, F);
410 Blas<Field>::copy(p.w, &Aext[p.r], 1, &A[i * p.w], 1);
413 static void column_hash(
size_t n,
const Elt x[],
size_t incx,
414 SHA256 &sha,
const Field &F) {
415 for (
size_t i = 0; i < n; ++i) {
416 uint8_t buf[Field::kBytes];
417 F.to_bytes_field(buf, x[i * incx]);
418 sha.Update(buf,
sizeof(buf));