@@ -290,6 +290,43 @@ void ReferenceForwardTransformToBitReverse(
290290 }
291291}
292292
293+ void ReferenceInverseTransformFromBitReverse (
294+ uint64_t * operand, uint64_t n, uint64_t modulus,
295+ const uint64_t * inv_root_of_unity_powers) {
296+ HEXL_CHECK (NTT::CheckArguments (n, modulus), " " );
297+ HEXL_CHECK (inv_root_of_unity_powers != nullptr ,
298+ " inv_root_of_unity_powers == nullptr" );
299+ HEXL_CHECK (operand != nullptr , " operand == nullptr" );
300+
301+ size_t t = 1 ;
302+ size_t root_index = 1 ;
303+ for (size_t m = (n >> 1 ); m >= 1 ; m >>= 1 ) {
304+ size_t j1 = 0 ;
305+ for (size_t i = 0 ; i < m; i++, root_index++) {
306+ const uint64_t W = inv_root_of_unity_powers[root_index];
307+ uint64_t * X_r = operand + j1;
308+ uint64_t * Y_r = X_r + t;
309+ for (size_t j = 0 ; j < t; j++) {
310+ uint64_t X_op = *X_r;
311+ uint64_t Y_op = *Y_r;
312+ // Butterfly X' = (X + Y) mod q, Y' = W(X-Y) mod q
313+ *X_r = AddUIntMod (X_op, Y_op, modulus);
314+ *Y_r = MultiplyMod (W, SubUIntMod (X_op, Y_op, modulus), modulus);
315+ X_r++;
316+ Y_r++;
317+ }
318+ j1 += (t << 1 );
319+ }
320+ t <<= 1 ;
321+ }
322+
323+ // Final multiplication by N^{-1}
324+ const uint64_t inv_n = InverseMod (n, modulus);
325+ for (size_t i = 0 ; i < n; ++i) {
326+ operand[i] = MultiplyMod (operand[i], inv_n, modulus);
327+ }
328+ }
329+
293330void InverseTransformFromBitReverseRadix2 (
294331 uint64_t * result, const uint64_t * operand, uint64_t n, uint64_t modulus,
295332 const uint64_t * inv_root_of_unity_powers,
0 commit comments