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