Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
fft.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_FFT_H_
16#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FFT_H_
17
18#include <stddef.h>
19#include <stdint.h>
20
21#include "algebra/permutations.h"
22#include "algebra/twiddle.h"
23
24namespace proofs {
25/*
26Fast Fourier Transform (FFT).
27
28We use FFTPACK/FFTW/MATLAB conventions where the FFT
29has a negative sign in the exponent. For root of unity
30W, input ("time") T and output ("frequency") F, the
31"forward" FFT computes
32
33 F[k] = SUM_{j} T[j] W^{-jk}
34
35and the "backward" fft computes
36
37 T[j] = SUM_{k} F[k] W^{jk}
38
39A forward transform followed by a backward transform
40multiplies the array by N.
41
42Matlab and engineers call the forward transform the FFT.
43Mathematicians tend to call the backward transform the FFT.
44*/
45template <class Field>
46class FFT {
47 using Elt = typename Field::Elt;
48
49 static void butterfly(Elt* A, size_t s, const Field& F) {
50 Elt t = A[s];
51 A[s] = A[0];
52 F.add(A[0], t);
53 F.sub(A[s], t);
54 }
55
56 static void butterflytw(Elt* A, size_t s, const Elt& twiddle,
57 const Field& F) {
58 Elt t = A[s];
59 F.mul(t, twiddle);
60 A[s] = A[0];
61 F.add(A[0], t);
62 F.sub(A[s], t);
63 }
64
65 public:
66 // Backward FFT.
67 // N (the length of A) must be a power of 2
68 static void fftb(Elt A[/*n*/], size_t n, const Elt& omega,
69 uint64_t omega_order, const Field& F) {
70 if (n <= 1) {
71 return;
72 }
73
74 Elt omega_n = Twiddle<Field>::reroot(omega, omega_order, n, F);
75 Twiddle<Field> roots(n, omega_n, F);
76
77 Permutations<Elt>::bitrev(A, n);
78
79 // m=1 iteration
80 for (size_t k = 0; k < n; k += 2) {
81 butterfly(&A[k], 1, F);
82 }
83
84 // m>1 iterations
85 for (size_t m = 2; m < n; m = 2 * m) {
86 size_t ws = n / (2 * m);
87 for (size_t k = 0; k < n; k += 2 * m) {
88 butterfly(&A[k], m, F); // j==0
89 for (size_t j = 1; j < m; ++j) {
90 butterflytw(&A[k + j], m, roots.w_[j * ws], F);
91 }
92 }
93 }
94 }
95
96 // forward transform
97 static void fftf(Elt A[/*n*/], size_t n, const Elt& omega,
98 uint64_t omega_order, const Field& F) {
99 fftb(A, n, F.invertf(omega), omega_order, F);
100 }
101};
102} // namespace proofs
103
104#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FFT_H_
Definition fft.h:46
Definition twiddle.h:27
Definition gf2_128.h:63