Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
lch14_reed_solomon.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_GF2K_LCH14_REED_SOLOMON_H_
16#define PRIVACY_PROOFS_ZK_LIB_GF2K_LCH14_REED_SOLOMON_H_
17
18#include <stdio.h>
19
20#include <algorithm>
21#include <memory>
22#include <vector>
23
24#include "gf2k/lch14.h"
25
26namespace proofs {
27
28template <class Field>
29class LCH14ReedSolomon {
30 using Elt = typename Field::Elt;
31
32 // only works in binary fields
33 static_assert(Field::kCharacteristicTwo);
34
35 public:
36 // We interpolate N points, assumed to be the evaluations at
37 // F.of_scalar(i), 0 <= i < N, of a polynomial of degree <N, to M
38 // points 0 <= i < M. (Thus, the M points include the N points
39 // we started with.)
40 //
41 // In principle we don't need to know N and M at construction time,
42 // but we require N and M for compatibility of the interface with
43 // the ReedSolomon class over prime fields.
44 LCH14ReedSolomon(size_t n, size_t m, const Field& F)
45 : f_(F), n_(n), m_(m), fft_(F) {}
46
47 // Y[i] is expected to be defined for 0 <= i < N, and this
48 // routine fills it for 0 <= i < M
49 void interpolate(Elt y[/*m*/]) const {
50 // determine the FFT size
51 size_t l = 0;
52 size_t fftn = 1;
53 while (fftn < n_) {
54 fftn <<= 1;
55 ++l;
56 }
57
58 // "coefficients" in the LCH14 novel polynomial basis
59 std::vector<Elt> C(fftn);
60
61 // compute the "coefficients" under the assumption
62 // that we know n_ evaluations and that the higher-order
63 // (fftn - n_) "coefficients" are zero.
64 for (size_t i = 0; i < n_; ++i) {
65 C[i] = y[i];
66 }
67 for (size_t i = n_; i < fftn; ++i) {
68 C[i] = f_.zero();
69 }
70 fft_.BidirectionalFFT(l, /*k=*/n_, &C[0]);
71
72 // fill in the missing evaluations in the first coset, since we
73 // already have the missing evaluations in C[[n_, (1<<l))]
74 for (size_t i = n_; i < std::min(m_, fftn); ++i) {
75 y[i] = C[i];
76 }
77
78 // revert C to pure coefficients for later use
79 for (size_t i = n_; i < fftn; ++i) {
80 C[i] = f_.zero();
81 }
82
83 // all remaining cosets:
84 for (size_t coset = 1; (coset << l) < m_; ++coset) {
85 size_t b = (coset << l);
86 if (b + fftn <= m_) {
87 // if the coset fits completely within Y[],
88 // copy the coefficients into Y and transform in place
89 for (size_t i = 0; i < fftn; ++i) {
90 y[i + b] = C[i];
91 }
92 fft_.FFT(l, b, &y[b]);
93 } else {
94 // Partial fit. Transform C and copy the output.
95 fft_.FFT(l, b, &C[0]);
96 for (size_t i = 0; i + b < m_; ++i) {
97 y[i + b] = C[i];
98 }
99 // Now we have destroyed C, but this is ok because
100 // this is the last iteration
101 }
102 }
103 }
104
105 private:
106 const Field& f_;
107 size_t n_;
108 size_t m_;
109 LCH14<Field> fft_;
110};
111
112template <class Field>
113class LCH14ReedSolomonFactory {
114 public:
115 explicit LCH14ReedSolomonFactory(const Field& f) : f_(f) {}
116
117 std::unique_ptr<LCH14ReedSolomon<Field>> make(size_t n, size_t m) const {
118 return std::make_unique<LCH14ReedSolomon<Field>>(n, m, f_);
119 }
120
121 private:
122 const Field& f_;
123};
124
125} // namespace proofs
126
127#endif // PRIVACY_PROOFS_ZK_LIB_GF2K_LCH14_REED_SOLOMON_H_
Definition lch14.h:36
Definition gf2_128.h:63