Annotation of embedaddon/strongswan/src/libstrongswan/math/libnttfft/ntt_fft.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014-2016 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "ntt_fft.h"
17: #include "ntt_fft_reduce.h"
18:
19: /**
20: * Described in header.
21: */
22: void libnttfft_init(void)
23: {
24: /* empty */
25: }
26:
27: typedef struct private_ntt_fft_t private_ntt_fft_t;
28:
29: /**
30: * Private data structure for ntt_fft_t object
31: */
32: struct private_ntt_fft_t {
33:
34: /**
35: * Public interface.
36: */
37: ntt_fft_t public;
38:
39: /**
40: * FFT parameter set used as constants
41: */
42: const ntt_fft_params_t *p;
43:
44: };
45:
46: METHOD(ntt_fft_t, get_size, uint16_t,
47: private_ntt_fft_t *this)
48: {
49: return this->p->n;
50: }
51:
52: METHOD(ntt_fft_t, get_modulus, uint16_t,
53: private_ntt_fft_t *this)
54: {
55: return this->p->q;
56: }
57:
58: /**
59: * Do an FFT butterfly operation
60: *
61: * x[i1] ---|+|------- x[i1]
62: * \/
63: * /\ w[iw]
64: * x[i2] ---|-|--|*|-- x[i2]
65: *
66: */
67: static void butterfly(private_ntt_fft_t *this, uint32_t *x, int i1,int i2, int iw)
68: {
69: uint32_t xp, xm;
70:
71: xp = x[i1] + x[i2];
72: xm = x[i1] + (this->p->q - x[i2]);
73: if (xp >= this->p->q)
74: {
75: xp -= this->p->q;
76: }
77: x[i1] = xp;
78: x[i2] = ntt_fft_mreduce(xm * this->p->wr[iw], this->p);
79: }
80:
81: /**
82: * Trivial butterfly operation of last FFT stage
83: */
84: static void butterfly_last(private_ntt_fft_t *this, uint32_t *x, int i1)
85: {
86: uint32_t xp, xm;
87: int i2 = i1 + 1;
88:
89: xp = x[i1] + x[i2];
90: xm = x[i1] + (this->p->q - x[i2]);
91: if (xp >= this->p->q)
92: {
93: xp -= this->p->q;
94: }
95: if (xm >= this->p->q)
96: {
97: xm -= this->p->q;
98: }
99: x[i1] = xp;
100: x[i2] = xm;
101: }
102:
103: METHOD(ntt_fft_t, transform, void,
104: private_ntt_fft_t *this, uint32_t *a, uint32_t *b, bool inverse)
105: {
106: int stage, i, j, k, m, n, s, t, iw, i_rev;
107: uint32_t tmp;
108:
109: /* we are going to use the transform size n a lot */
110: n = this->p->n;
111: s = this->p->s;
112:
113: if (!inverse)
114: {
115: /* apply linear phase needed for negative wrapped convolution */
116: for (i = 0; i < n; i++)
117: {
118: b[i] = ntt_fft_mreduce(a[i] * this->p->wf[s*i], this->p);
119: }
120: }
121: else if (a != b)
122: {
123: /* copy if input and output array are not the same */
124: for (i = 0; i < n; i++)
125: {
126: b[i] = a[i];
127: }
128: }
129:
130: m = n;
131: k = 1;
132:
133: for (stage = this->p->stages; stage > 0; stage--)
134: {
135: m >>= 1;
136: t = 0;
137:
138: for (j = 0; j < k; j++)
139: {
140: if (stage == 1)
141: {
142: butterfly_last(this, b, t);
143: }
144: else
145: {
146: for (i = 0; i < m; i++)
147: {
148: iw = s * (inverse ? (n - i * k) : (i * k));
149: butterfly(this, b, t + i, t + i + m, iw);
150: }
151: }
152: t += 2*m;
153: }
154: k <<= 1;
155: }
156:
157: /* Sort output in bit-reverse order */
158: for (i = 0; i < n; i++)
159: {
160: i_rev = this->p->rev[i];
161:
162: if (i_rev > i)
163: {
164: tmp = b[i];
165: b[i] = b[i_rev];
166: b[i_rev] = tmp;
167: }
168: }
169:
170: /**
171: * Compensate the linear phase needed for negative wrapped convolution
172: * and normalize the output array with 1/n mod q after the inverse FFT.
173: */
174: if (inverse)
175: {
176: for (i = 0; i < n; i++)
177: {
178: b[i] = ntt_fft_mreduce(b[i] * this->p->wi[i], this->p);
179: }
180: }
181: }
182:
183: METHOD(ntt_fft_t, destroy, void,
184: private_ntt_fft_t *this)
185: {
186: free(this);
187: }
188:
189: /**
190: * See header.
191: */
192: ntt_fft_t *ntt_fft_create(const ntt_fft_params_t *params)
193: {
194: private_ntt_fft_t *this;
195:
196: INIT(this,
197: .public = {
198: .get_size = _get_size,
199: .get_modulus = _get_modulus,
200: .transform = _transform,
201: .destroy = _destroy,
202: },
203: .p = params,
204: );
205:
206: return &this->public;
207: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>