Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
circuit.h
1// Copyright 2025 Google LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef PRIVACY_PROOFS_ZK_LIB_SUMCHECK_CIRCUIT_H_
16#define PRIVACY_PROOFS_ZK_LIB_SUMCHECK_CIRCUIT_H_
17
18#include <stddef.h>
19
20#include <cstdint>
21#include <memory>
22#include <vector>
23
24#include "algebra/poly.h"
25#include "arrays/affine.h"
26#include "sumcheck/quad.h"
27
28namespace proofs {
29template <class Field>
30struct Layer {
31 corner_t nw; // number of inputs
32 size_t logw; // number of binding rounds for the hand variables
33 std::unique_ptr<const Quad<Field>> quad;
34
35 bool operator==(const Layer& y) const {
36 // This operator relies on the layer being properly constructed, so that
37 // the quad reference is never a nullptr.
38 return nw == y.nw && logw == y.logw && *quad == *y.quad;
39 }
40
41 size_t nterms() const { return quad->n_; }
42};
43
44template <class Field>
45struct Circuit {
46 corner_t nv; // number of outputs for one copy
47 size_t logv; // number of G variables in V[G,C] in the final output
48 corner_t nc; // number of copies
49 size_t logc; // number of sumcheck rounds for the C variables
50 size_t nl; // number of layers
51
52 size_t ninputs; // number of inputs
53 size_t npub_in; // number of public inputs, index of first private input
54 size_t subfield_boundary; // Least input wire not known to be in the
55 // subfield
56
57 std::vector<Layer<Field>> l; // layers
58
59 uint8_t id[32]; // unique id for the circuit, created by the compiler
60
61 bool operator==(const Circuit& y) const {
62 return nv == y.nv && logv == y.logv && nc == y.nc && logc == y.logc &&
63 nl == y.nl && l == y.l;
64 }
65 size_t nterms() const {
66 size_t n = 0;
67 for (const auto& layer : l) {
68 n += layer.nterms();
69 }
70 return n;
71 }
72};
73
74template <class Field>
75struct LayerProof {
76 using Elt = typename Field::Elt;
77 // For efficiency, we distinguish polynomials needed to bind copy
78 // variables (CPoly, degree 3) from polynomials needed to bind
79 // wire variables (WPoly, degree 2).
80 using CPoly = Poly<4, Field>;
81 using WPoly = Poly<3, Field>;
82
83 // Maximum 2^40 gates/wires/copies per layer.
84 static constexpr size_t kMaxBindings = 40;
85
86 CPoly cp[kMaxBindings]; // polys for the C variables
87
88 // The binding order we use is "for (round) { for (hand) ... }", and
89 // thus one can organize this array as [kMaxBindings][2] for better
90 // memory locality.
91 // However, the corresponding challenges are organized as [2][kMaxBindings]
92 // to allow easier binding by hand, and so it makes sense to keep this
93 // array in the same order as the challenges.
94 WPoly hp[2][kMaxBindings]; // polys for each hand \in {right,left}
95
96 // prover provides W[R,C] and W[L,C], which serve as claims
97 // for the next layer
98 Elt wc[2];
99};
100
101template <class Field>
103 using Elt = typename Field::Elt;
104 static constexpr size_t kMaxBindings = LayerProof<Field>::kMaxBindings;
105
106 // verifier: coefficient for the random linear combination
107 // claim[0] + alpha * claim[1] of the two input claims.
108 Elt alpha;
109 Elt beta; // random coefficient for assert-zero
110 Elt cb[kMaxBindings]; // bindings for the C variables
111 Elt hb[2][kMaxBindings]; // bindings for each hand
112};
113
114template <class Field>
115struct Challenge {
116 using Elt = typename Field::Elt;
117 static constexpr size_t kMaxBindings = LayerProof<Field>::kMaxBindings;
118
119 // verifier picks Q for EQ[Q|c]
120 Elt q[kMaxBindings]; // [logC]
121
122 // verifier picks G for V[G,c]
123 Elt g[kMaxBindings]; // [logV]
124 std::vector<LayerChallenge<Field>> l;
125 explicit Challenge(size_t nl) : l(nl) {}
126};
127
128// Full proof:
129template <class Field>
130struct Proof {
131 typedef typename LayerProof<Field>::CPoly CPoly;
132 typedef typename LayerProof<Field>::WPoly WPoly;
133
134 using Elt = typename Field::Elt;
135 static constexpr size_t kMaxBindings = LayerProof<Field>::kMaxBindings;
136
137 // then engage in sumcheck one per layer
138 std::vector<LayerProof<Field>> l;
139
140 explicit Proof(size_t nl) : l(nl) {}
141 size_t size() const {
142 return l.size() * (kMaxBindings * 4 + kMaxBindings * 3 * 2 + 2);
143 }
144};
145
146// Auxiliary information generated by the prover to be
147// used by the ZK prover
148template <class Field>
149struct ProofAux {
150 using Elt = typename Field::Elt;
151 std::vector<Elt> bound_quad;
152 explicit ProofAux(size_t nl) : bound_quad(nl) {}
153};
154} // namespace proofs
155
156#endif // PRIVACY_PROOFS_ZK_LIB_SUMCHECK_CIRCUIT_H_
Definition poly.h:24
Definition circuit.h:45
Definition gf2_128.h:63
Definition circuit.h:102
Definition circuit.h:75
Definition circuit.h:30