Longfellow ZK 0290cb32

Loading...
Searching...
No Matches
interpolation.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_ALGEBRA_INTERPOLATION_H_
16#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_INTERPOLATION_H_
17
18#include <cstddef>
19
20#include "algebra/poly.h"
21
22 namespace proofs {
23// General-purpose polynomial interpolation routines,
24// which operate on arbitrary points at the cost of
25// computing inverses in the field.
26// These static functions are grouped into a class due
27// to the common template arguments.
28 template <size_t N, class Field>
29 class Interpolation {
30 public:
31 static const size_t kN = N;
32 using Elt = typename Field::Elt;
33 using PolyN = Poly<N, Field>;
34
35 // Throughout, X are the evaluation points.
36
37 // Lagrange basis to Newton
38 static void newton_of_lagrange_inplace(PolyN &A, const PolyN &X,
39 const Field &F) {
40 // Cache one element E and its inverse. In the common
41 // case where the points X are in an arithmetic sequence,
42 // this cache avoids the computation of most inverses.
43 Elt e = F.one(), inve = F.one();
44
45 for (size_t i = 1; i < N; i++) {
46 for (size_t k = N; k-- > i;) {
47 Elt dx = F.subf(X[k], X[k - i]);
48 if (dx != e) {
49 e = dx;
50 inve = F.invertf(dx);
51 }
52 A[k] = F.mulf(F.subf(A[k], A[k - 1]), inve);
53 }
54 }
55 }
56
57 static PolyN newton_of_lagrange(const PolyN &L, const PolyN &X,
58 const Field &F) {
59 PolyN A = L;
60 newton_of_lagrange_inplace(A, X, F);
61 return A;
62 }
63
64 // evaluation in Newton basis
65 static Elt eval_newton(PolyN &Newton, const PolyN &X, const Elt &x,
66 const Field &F) {
67 Elt e{};
68
69 for (size_t i = N; i-- > 0;) {
70 e = F.addf(Newton[i], F.mulf(e, F.subf(x, X[i])));
71 }
72 return e;
73 }
74
75 // Newton basis to monomial basis (i.e., coefficients)
76 static void monomial_of_newton_inplace(PolyN &A, const PolyN &X,
77 const Field &F) {
78 for (size_t i = N; i-- > 0;) {
79 for (size_t k = i + 1; k < N; ++k) {
80 A[k - 1] = F.subf(A[k - 1], F.mulf(A[k], X[i]));
81 }
82 }
83 }
84
85 static PolyN monomial_of_newton(const PolyN &Newton, const PolyN &X,
86 const Field &F) {
87 PolyN A = Newton;
88 monomial_of_newton_inplace(A, X, F);
89 return A;
90 }
91
92 // evaluation in the monomial basis
93 static Elt eval_monomial(PolyN &M, const Elt &x, const Field &F) {
94 Elt e{};
95
96 for (size_t i = N; i-- > 0;) {
97 e = F.addf(M[i], F.mulf(e, x));
98 }
99 return e;
100 }
101
102 static void monomial_of_lagrange_inplace(PolyN &A, const PolyN &X,
103 const Field &F) {
104 newton_of_lagrange_inplace(A, X, F);
105 monomial_of_newton_inplace(A, X, F);
106 }
107
108 static PolyN monomial_of_lagrange(const PolyN &L, const PolyN &X,
109 const Field &F) {
110 PolyN A = L;
111 monomial_of_lagrange_inplace(A, X, F);
112 return A;
113 }
114};
115} // namespace proofs
116
117#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_INTERPOLATION_H_
proofs::Interpolation
Definition interpolation.h:29
proofs::Poly
Definition poly.h:30
proofs::GF2_128::Elt
Definition gf2_128.h:63