@@ -72,13 +72,20 @@ fn radix(f0: &mut [u16], f1: &mut [u16], f: &[u16], m_f: usize) {
7272
7373/// Radix conversion for larger sizes.
7474fn radix_big ( f0 : & mut [ u16 ] , f1 : & mut [ u16 ] , f : & [ u16 ] , m_f : usize ) {
75+ // m_f <= fft parameter (max 5), so n <= 8; buffers bounded accordingly.
7576 let n = 1usize << ( m_f - 2 ) ;
76- let mut q = vec ! [ 0u16 ; 2 * n + 1 ] ;
77- let mut r = vec ! [ 0u16 ; 4 * n] ;
78- let mut q0 = vec ! [ 0u16 ; n] ;
79- let mut q1 = vec ! [ 0u16 ; n] ;
80- let mut r0 = vec ! [ 0u16 ; n] ;
81- let mut r1 = vec ! [ 0u16 ; n] ;
77+ let mut q = [ 0u16 ; 17 ] ;
78+ let q = & mut q[ ..2 * n + 1 ] ;
79+ let mut r = [ 0u16 ; 32 ] ;
80+ let r = & mut r[ ..4 * n] ;
81+ let mut q0 = [ 0u16 ; 8 ] ;
82+ let q0 = & mut q0[ ..n] ;
83+ let mut q1 = [ 0u16 ; 8 ] ;
84+ let q1 = & mut q1[ ..n] ;
85+ let mut r0 = [ 0u16 ; 8 ] ;
86+ let r0 = & mut r0[ ..n] ;
87+ let mut r1 = [ 0u16 ; 8 ] ;
88+ let r1 = & mut r1[ ..n] ;
8289
8390 q[ ..n] . copy_from_slice ( & f[ 3 * n..4 * n] ) ;
8491 q[ n..2 * n] . copy_from_slice ( & f[ 3 * n..4 * n] ) ;
@@ -89,8 +96,8 @@ fn radix_big(f0: &mut [u16], f1: &mut [u16], f: &[u16], m_f: usize) {
8996 r[ n + i] ^= q[ i] ;
9097 }
9198
92- radix ( & mut q0, & mut q1, & q, m_f - 1 ) ;
93- radix ( & mut r0, & mut r1, & r, m_f - 1 ) ;
99+ radix ( q0, q1, q, m_f - 1 ) ;
100+ radix ( r0, r1, r, m_f - 1 ) ;
94101
95102 f0[ ..n] . copy_from_slice ( & r0[ ..n] ) ;
96103 f0[ n..2 * n] . copy_from_slice ( & q0[ ..n] ) ;
@@ -116,9 +123,12 @@ fn fft_rec(w: &mut [u16], f: &mut [u16], f_coeffs: usize, m: usize, m_f: usize,
116123 return ;
117124 }
118125
126+ // m_f <= 5 throughout the recursion, so half_size <= 16.
119127 let half_size = 1 << ( m_f - 1 ) ;
120- let mut f0 = vec ! [ 0u16 ; half_size] ;
121- let mut f1 = vec ! [ 0u16 ; half_size] ;
128+ let mut f0 = [ 0u16 ; 16 ] ;
129+ let f0 = & mut f0[ ..half_size] ;
130+ let mut f1 = [ 0u16 ; 16 ] ;
131+ let f1 = & mut f1[ ..half_size] ;
122132
123133 // Step 2: twist by beta_m
124134 if betas[ m - 1 ] != 1 {
@@ -131,32 +141,29 @@ fn fft_rec(w: &mut [u16], f: &mut [u16], f_coeffs: usize, m: usize, m_f: usize,
131141 }
132142
133143 // Step 3: radix
134- radix ( & mut f0, & mut f1, f, m_f) ;
144+ radix ( f0, f1, f, m_f) ;
135145
136- // Step 4: compute gammas and deltas
137- let mut gammas = vec ! [ 0u16 ; m] ;
138- let mut deltas = vec ! [ 0u16 ; m] ;
146+ // Step 4: compute gammas and deltas (m <= PARAM_M - 1 = 7)
147+ let mut gammas = [ 0u16 ; 8 ] ;
148+ let gammas = & mut gammas[ ..m] ;
149+ let mut deltas = [ 0u16 ; 8 ] ;
150+ let deltas = & mut deltas[ ..m] ;
139151 let inv_beta_m = gf_inverse ( betas[ m - 1 ] ) ;
140152 for i in 0 ..m - 1 {
141153 gammas[ i] = gf_mul ( betas[ i] , inv_beta_m) ;
142154 deltas[ i] = gf_square ( gammas[ i] ) ^ gammas[ i] ;
143155 }
144156
145- // Compute gamma sums
146- let mut gammas_sums = vec ! [ 0u16 ; 1 << ( m - 1 ) ] ;
147- compute_subset_sums ( & mut gammas_sums, & gammas, m - 1 ) ;
157+ // Compute gamma sums (1 << (m - 1) <= 64)
158+ let mut gammas_sums = [ 0u16 ; 64 ] ;
159+ let gammas_sums = & mut gammas_sums[ ..1 << ( m - 1 ) ] ;
160+ compute_subset_sums ( gammas_sums, gammas, m - 1 ) ;
148161
149- // Step 5: recurse
162+ // Step 5: recurse (k <= 64)
150163 let k = 1usize << ( m - 1 ) ;
151- let mut u = vec ! [ 0u16 ; k] ;
152- fft_rec (
153- & mut u,
154- & mut f0,
155- f_coeffs. div_ceil ( 2 ) ,
156- m - 1 ,
157- m_f - 1 ,
158- & deltas,
159- ) ;
164+ let mut u = [ 0u16 ; 64 ] ;
165+ let u = & mut u[ ..k] ;
166+ fft_rec ( u, f0, f_coeffs. div_ceil ( 2 ) , m - 1 , m_f - 1 , deltas) ;
160167
161168 if f_coeffs <= 3 {
162169 // f1 is constant
@@ -167,8 +174,9 @@ fn fft_rec(w: &mut [u16], f: &mut [u16], f_coeffs: usize, m: usize, m_f: usize,
167174 w[ k + i] = w[ i] ^ f1[ 0 ] ;
168175 }
169176 } else {
170- let mut v = vec ! [ 0u16 ; k] ;
171- fft_rec ( & mut v, & mut f1, f_coeffs / 2 , m - 1 , m_f - 1 , & deltas) ;
177+ let mut v = [ 0u16 ; 64 ] ;
178+ let v = & mut v[ ..k] ;
179+ fft_rec ( v, f1, f_coeffs / 2 , m - 1 , m_f - 1 , deltas) ;
172180
173181 // Step 6: combine
174182 w[ k..k + k] . copy_from_slice ( & v[ ..k] ) ;
@@ -191,35 +199,39 @@ pub(crate) fn fft(w: &mut [u16; 256], f: &[u16], f_coeffs: usize, fft_param: usi
191199 let mut betas_sums = [ 0u16 ; 1 << ( PARAM_M - 1 ) ] ;
192200 compute_subset_sums ( & mut betas_sums, & betas, PARAM_M - 1 ) ;
193201
202+ // fft_param <= 5, so fft_size <= 32 and half <= 16.
194203 let fft_size = 1 << fft_param;
195- let mut f_padded = vec ! [ 0u16 ; fft_size] ;
204+ let mut f_padded = [ 0u16 ; 32 ] ;
205+ let f_padded = & mut f_padded[ ..fft_size] ;
196206 f_padded[ ..f_coeffs. min ( fft_size) ] . copy_from_slice ( & f[ ..f_coeffs. min ( fft_size) ] ) ;
197207
198208 let half = fft_size >> 1 ;
199- let mut f0 = vec ! [ 0u16 ; half] ;
200- let mut f1 = vec ! [ 0u16 ; half] ;
201- radix ( & mut f0, & mut f1, & f_padded, fft_param) ;
209+ let mut f0 = [ 0u16 ; 16 ] ;
210+ let f0 = & mut f0[ ..half] ;
211+ let mut f1 = [ 0u16 ; 16 ] ;
212+ let f1 = & mut f1[ ..half] ;
213+ radix ( f0, f1, f_padded, fft_param) ;
202214
203215 let mut deltas = [ 0u16 ; PARAM_M - 1 ] ;
204216 for i in 0 ..( PARAM_M - 1 ) {
205217 deltas[ i] = gf_square ( betas[ i] ) ^ betas[ i] ;
206218 }
207219
208220 let k = 1usize << ( PARAM_M - 1 ) ;
209- let mut u = vec ! [ 0u16 ; k ] ;
210- let mut v = vec ! [ 0u16 ; k ] ;
221+ let mut u = [ 0u16 ; 1 << ( PARAM_M - 1 ) ] ;
222+ let mut v = [ 0u16 ; 1 << ( PARAM_M - 1 ) ] ;
211223
212224 fft_rec (
213225 & mut u,
214- & mut f0,
226+ f0,
215227 f_coeffs. div_ceil ( 2 ) ,
216228 PARAM_M - 1 ,
217229 fft_param - 1 ,
218230 & deltas,
219231 ) ;
220232 fft_rec (
221233 & mut v,
222- & mut f1,
234+ f1,
223235 f_coeffs / 2 ,
224236 PARAM_M - 1 ,
225237 fft_param - 1 ,
0 commit comments