Longfellow ZK 0290cb32

Loading...
Searching...
No Matches
eq.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_ARRAYS_EQ_H_
16#define PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQ_H_
17
18#include <stddef.h>
19
20#include "arrays/affine.h"
21
22 namespace proofs {
23 template <class Field>
24// EQ[i,j] is 2D sparse array EQ[i, j] = (i == j).
25// This class contains a state-free version of EQ, which
26// evaluates EQ[i, j] on the fly. See Eqs for a stateful
27// version that stores all the values of EQ[I, j] for fixed I
28// and variable j.
29 class Eq {
30 using Elt = typename Field::Elt;
31
32 public:
33 /*
34 Bind EQ{logn,n} at I, J.
35
36 We consider the diagonal matrix EQ[i,j] to be composed of
37 N-1 diagonal elements A and one last diagonal element B, i.e.,
38 EQ=diag([A A A A ... B]). We bind one I variable and one J
39 variable in one step, yielding a matrix of the same form
40 with ceil(n/2) diagonal entries.
41
42 Let I1J1=I[0]*J[0] and I0J0=(1-I[0])*(1-J[0]).
43
44 Binding A is equivalent to binding the 2x2 block [A 0; 0 A],
45 yielding A <- A*(I0J0+I1J1).
46
47 If n is even, then the last 2x2 block is [A 0; 0 B], whose binding
48 yields B <- A*I0J0 + B*I1J1.
49
50 If n is odd, then the last 2x2 block is [B 0; 0 0], whose binding
51 yields B <- B*I0J0.
52 */
53 static Elt eval(size_t logn, corner_t n, const Elt I[/*logn*/],
54 const Elt J[/*logn*/], const Field& F) {
55 Elt a = F.one(), b = F.one();
56 for (size_t round = 0; round < logn; round++) {
57 Elt i1 = I[round], j1 = J[round];
58 Elt i0 = F.subf(F.one(), i1), j0 = F.subf(F.one(), j1);
59 Elt i0j0 = F.mulf(i0, j0);
60 Elt i1j1 = F.mulf(i1, j1);
61 if ((n & 1) == 0) {
62 F.mul(b, i1j1);
63 F.add(b, F.mulf(a, i0j0));
64 } else {
65 F.mul(b, i0j0);
66 }
67 F.mul(a, F.addf(i0j0, i1j1));
68 n = (n + 1) / 2;
69 }
70 return b;
71 }
72};
73} // namespace proofs
74
75#endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQ_H_
proofs::Eq
Definition eq.h:29
proofs::GF2_128::Elt
Definition gf2_128.h:63