77// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
88
99//! This module contains implementations to construct [`NTTBasisPolynomialRingZq`] for the
10- //! NTT-transform for [`PolyOverZq`] objects in the polynomialring.
10+ //! NTT-transform for [`PolyOverZq`](crate::integer_mod_q::PolyOverZq) objects in the polynomialring.
1111//!
1212//! The explicit functions contain the documentation.
1313
@@ -80,24 +80,51 @@ impl NTTBasisPolynomialRingZq {
8080 } ;
8181
8282 // precompute powers of `n`th root of unity
83- let powers_of_omega = ( 0 ..n) . map ( |i| omega. pow ( i) . unwrap ( ) ) . collect ( ) ;
84- let powers_of_omega_inv = ( 0 ..n) . map ( |i| omega_inv. pow ( i) . unwrap ( ) ) . collect ( ) ;
83+ let powers_of_omega = ( 0 ..n)
84+ . map ( |i| {
85+ omega
86+ . pow ( i)
87+ . unwrap ( )
88+ . get_representative_least_nonnegative_residue ( )
89+ } )
90+ . collect ( ) ;
91+ let powers_of_omega_inv = ( 0 ..n)
92+ . map ( |i| {
93+ omega_inv
94+ . pow ( i)
95+ . unwrap ( )
96+ . get_representative_least_nonnegative_residue ( )
97+ } )
98+ . collect ( ) ;
8599
86100 // precompute powers of `2n`th root of unity
87101 let powers_of_psi = match convolution_type {
88102 ConvolutionType :: Cyclic => Vec :: new ( ) ,
89- ConvolutionType :: Negacyclic => ( 0 ..n) . map ( |i| psi. unwrap ( ) . pow ( i) . unwrap ( ) ) . collect ( ) ,
103+ ConvolutionType :: Negacyclic => ( 0 ..n)
104+ . map ( |i| {
105+ psi. unwrap ( )
106+ . pow ( i)
107+ . unwrap ( )
108+ . get_representative_least_nonnegative_residue ( )
109+ } )
110+ . collect ( ) ,
90111 } ;
91112 let powers_of_psi_inv = match convolution_type {
92113 ConvolutionType :: Cyclic => Vec :: new ( ) ,
93- ConvolutionType :: Negacyclic => {
94- ( 0 ..n) . map ( |i| psi_inv. unwrap ( ) . pow ( i) . unwrap ( ) ) . collect ( )
95- }
114+ ConvolutionType :: Negacyclic => ( 0 ..n)
115+ . map ( |i| {
116+ psi_inv
117+ . unwrap ( )
118+ . pow ( i)
119+ . unwrap ( )
120+ . get_representative_least_nonnegative_residue ( )
121+ } )
122+ . collect ( ) ,
96123 } ;
97124
98125 Self {
99126 n,
100- n_inv,
127+ n_inv : n_inv . get_representative_least_nonnegative_residue ( ) ,
101128 powers_of_omega,
102129 powers_of_omega_inv,
103130 powers_of_psi,
@@ -122,7 +149,7 @@ mod test_init {
122149 use super :: ConvolutionType ;
123150 use crate :: {
124151 integer:: Z ,
125- integer_mod_q:: { Modulus , NTTBasisPolynomialRingZq , Zq } ,
152+ integer_mod_q:: { Modulus , NTTBasisPolynomialRingZq } ,
126153 } ;
127154
128155 /// Our algorithm only supports complete splits as of right now, so other inputs should be prohibited for now.
@@ -140,30 +167,15 @@ mod test_init {
140167 assert_eq ! ( ConvolutionType :: Cyclic , ntt_basis. convolution_type) ;
141168 assert_eq ! ( Modulus :: from( 7681 ) , ntt_basis. modulus) ;
142169 assert_eq ! ( 4 , ntt_basis. n) ;
143- assert_eq ! (
144- Z :: from( 5761 ) ,
145- ntt_basis
146- . n_inv
147- . get_representative_least_nonnegative_residue( )
148- ) ;
170+ assert_eq ! ( Z :: from( 5761 ) , ntt_basis. n_inv) ;
149171 assert ! ( ntt_basis. powers_of_psi. is_empty( ) ) ;
150172 assert ! ( ntt_basis. powers_of_psi_inv. is_empty( ) ) ;
151173 assert_eq ! (
152- vec![
153- Zq :: from( ( 1 , 7681 ) ) ,
154- Zq :: from( ( 3383 , 7681 ) ) ,
155- Zq :: from( ( 7680 , 7681 ) ) ,
156- Zq :: from( ( 4298 , 7681 ) )
157- ] ,
174+ vec![ Z :: from( 1 ) , Z :: from( 3383 ) , Z :: from( 7680 ) , Z :: from( 4298 ) ] ,
158175 ntt_basis. powers_of_omega
159176 ) ;
160177 assert_eq ! (
161- vec![
162- Zq :: from( ( 1 , 7681 ) ) ,
163- Zq :: from( ( 4298 , 7681 ) ) ,
164- Zq :: from( ( 7680 , 7681 ) ) ,
165- Zq :: from( ( 3383 , 7681 ) )
166- ] ,
178+ vec![ Z :: from( 1 ) , Z :: from( 4298 ) , Z :: from( 7680 ) , Z :: from( 3383 ) ] ,
167179 ntt_basis. powers_of_omega_inv
168180 ) ;
169181 }
@@ -176,46 +188,21 @@ mod test_init {
176188 assert_eq ! ( ConvolutionType :: Negacyclic , ntt_basis. convolution_type) ;
177189 assert_eq ! ( Modulus :: from( 7681 ) , ntt_basis. modulus) ;
178190 assert_eq ! ( 4 , ntt_basis. n) ;
191+ assert_eq ! ( Z :: from( 5761 ) , ntt_basis. n_inv) ;
179192 assert_eq ! (
180- Z :: from( 5761 ) ,
181- ntt_basis
182- . n_inv
183- . get_representative_least_nonnegative_residue( )
184- ) ;
185- assert_eq ! (
186- vec![
187- Zq :: from( ( 1 , 7681 ) ) ,
188- Zq :: from( ( 1925 , 7681 ) ) ,
189- Zq :: from( ( 3383 , 7681 ) ) ,
190- Zq :: from( ( 6468 , 7681 ) )
191- ] ,
193+ vec![ Z :: from( 1 ) , Z :: from( 1925 ) , Z :: from( 3383 ) , Z :: from( 6468 ) ] ,
192194 ntt_basis. powers_of_psi
193195 ) ;
194196 assert_eq ! (
195- vec![
196- Zq :: from( ( 1 , 7681 ) ) ,
197- Zq :: from( ( 1213 , 7681 ) ) ,
198- Zq :: from( ( 4298 , 7681 ) ) ,
199- Zq :: from( ( 5756 , 7681 ) )
200- ] ,
197+ vec![ Z :: from( 1 ) , Z :: from( 1213 ) , Z :: from( 4298 ) , Z :: from( 5756 ) ] ,
201198 ntt_basis. powers_of_psi_inv
202199 ) ;
203200 assert_eq ! (
204- vec![
205- Zq :: from( ( 1 , 7681 ) ) ,
206- Zq :: from( ( 3383 , 7681 ) ) ,
207- Zq :: from( ( 7680 , 7681 ) ) ,
208- Zq :: from( ( 4298 , 7681 ) )
209- ] ,
201+ vec![ Z :: from( 1 ) , Z :: from( 3383 ) , Z :: from( 7680 ) , Z :: from( 4298 ) ] ,
210202 ntt_basis. powers_of_omega
211203 ) ;
212204 assert_eq ! (
213- vec![
214- Zq :: from( ( 1 , 7681 ) ) ,
215- Zq :: from( ( 4298 , 7681 ) ) ,
216- Zq :: from( ( 7680 , 7681 ) ) ,
217- Zq :: from( ( 3383 , 7681 ) )
218- ] ,
205+ vec![ Z :: from( 1 ) , Z :: from( 4298 ) , Z :: from( 7680 ) , Z :: from( 3383 ) ] ,
219206 ntt_basis. powers_of_omega_inv
220207 ) ;
221208 }
0 commit comments