Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
scan.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_CIRCUITS_CBOR_PARSER_SCAN_H_
16#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_CBOR_PARSER_SCAN_H_
17
18#include <stddef.h>
19
20#include <vector>
21
22namespace proofs {
23template <class Logic>
24class Scan {
25 public:
26 using EltW = typename Logic::EltW;
27 using BitW = typename Logic::BitW;
28
29 explicit Scan(const Logic& l) : l_(l) {}
30
31 /* Segmented prefix add, equivalent to this code:
32
33 s = 0;
34 for (size_t i = 0; i < n; ++i) {
35 if (S[i]) {
36 s = A[i];
37 } else {
38 s += ds[i];
39 }
40 B[i] = s;
41 }
42 */
43 void add(size_t n, EltW B[/*n*/], const BitW S[/*n*/], const EltW A[/*n*/],
44 const EltW ds[/*n*/]) {
45 const Logic& L = l_; // shorthand
46 std::vector<BitW> S1(n);
47 for (size_t i = 0; i < n; ++i) {
48 S1[i] = S[i];
49 B[i] = L.mux(&S[i], &A[i], ds[i]);
50 }
51 scan_add(0, n, S1.data(), B);
52 }
53
54 // unsegmented variant of add(), assume S[i] = false
55 void add(size_t n, EltW B[/*n*/], const EltW ds[/*n*/]) {
56 for (size_t i = 0; i < n; ++i) {
57 B[i] = ds[i];
58 }
59 scan_add(0, n, B);
60 }
61
62 private:
63 const Logic& l_;
64
65 void scan_add(size_t i0, size_t i1, BitW S[/*n*/], EltW B[/*n*/]) {
66 if (i1 - i0 > 1) {
67 const Logic& L = l_; // shorthand
68 size_t im = i0 + (i1 - i0) / 2;
69 scan_add(i0, im, S, B);
70 scan_add(im, i1, S, B);
71
72 size_t j = im - 1;
73 for (size_t i = im; i < i1; ++i) {
74 // special case of B[i] = S[i] ? B[i] : B[i] + B[j]
75 // coded as B[i] = B[i] + (~S[i] * B[j])
76 auto ns = L.lnot(S[i]);
77 auto ns_bj = L.lmul(&ns, B[j]);
78 B[i] = L.add(&B[i], ns_bj);
79 S[i] = L.lor(&S[i], S[j]);
80 }
81 }
82 }
83
84 // unsegmented
85 void scan_add(size_t i0, size_t i1, EltW B[/*n*/]) {
86 if (i1 - i0 > 1) {
87 const Logic& L = l_; // shorthand
88 size_t im = i0 + (i1 - i0) / 2;
89 scan_add(i0, im, B);
90 scan_add(im, i1, B);
91
92 size_t j = im - 1;
93 for (size_t i = im; i < i1; ++i) {
94 B[i] = L.add(&B[j], B[i]);
95 }
96 }
97 }
98};
99} // namespace proofs
100
101#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_CBOR_PARSER_SCAN_H_
Definition logic.h:38
Definition logic.h:130