@@ -190,7 +190,10 @@ class RnsPolynomial {
190190 return output;
191191 }
192192
193- // Adds `that` to `this` in-place.
193+ // Adds `that` to `this` in-place. May fail if the coefficient vectors of
194+ // `this` and `that` are not the same size, or the number of coefficient
195+ // vectors does not match the number of moduli. In case of failure, `this`
196+ // is not modified.
194197 absl::Status AddInPlace (
195198 const RnsPolynomial& that,
196199 absl::Span<const PrimeModulus<ModularInt>* const > moduli) {
@@ -203,14 +206,28 @@ class RnsPolynomial {
203206 return absl::InvalidArgumentError (
204207 absl::StrCat (" `moduli` must contain " , num_moduli, " RNS moduli." ));
205208 }
209+ // Check all coeff vectors have the right size to catch errors before
210+ // modifying `this`.
206211 for (int i = 0 ; i < num_moduli; ++i) {
207- RLWE_RETURN_IF_ERROR (ModularInt::BatchAddInPlace (
208- &coeff_vectors_[i], that.coeff_vectors_ [i], moduli[i]->ModParams ()));
212+ if (coeff_vectors_[i].size () != that.coeff_vectors_ [i].size ()) {
213+ return absl::InvalidArgumentError (
214+ absl::StrCat (" Size of coefficient vector " , i, " does not match" ));
215+ }
216+ }
217+ for (int i = 0 ; i < num_moduli; ++i) {
218+ ModularInt::BatchAddInPlace (&coeff_vectors_[i], that.coeff_vectors_ [i],
219+ moduli[i]->ModParams ())
220+ .IgnoreError (); // We already checked the sizes above, and
221+ // BatchAddInPlace will only fail if its inputs have
222+ // different sizes.
209223 }
210224 return absl::OkStatus ();
211225 }
212226
213- // Substracts `that` from `this` in-place.
227+ // Substracts `that` from `this` in-place. May fail if the coefficient
228+ // vectors of `this` and `that` are not the same size, or the number of
229+ // coefficient vectors does not match the number of moduli. In case of
230+ // failure, `this` is not modified.
214231 absl::Status SubInPlace (
215232 const RnsPolynomial& that,
216233 absl::Span<const PrimeModulus<ModularInt>* const > moduli) {
@@ -223,9 +240,20 @@ class RnsPolynomial {
223240 return absl::InvalidArgumentError (
224241 absl::StrCat (" `moduli` must contain " , num_moduli, " RNS moduli." ));
225242 }
243+ // Check all coeff vectors have the right size to catch errors before
244+ // modifying `this`.
245+ for (int i = 0 ; i < num_moduli; ++i) {
246+ if (coeff_vectors_[i].size () != that.coeff_vectors_ [i].size ()) {
247+ return absl::InvalidArgumentError (
248+ absl::StrCat (" Size of coefficient vector " , i, " does not match" ));
249+ }
250+ }
226251 for (int i = 0 ; i < num_moduli; ++i) {
227- RLWE_RETURN_IF_ERROR (ModularInt::BatchSubInPlace (
228- &coeff_vectors_[i], that.coeff_vectors_ [i], moduli[i]->ModParams ()));
252+ ModularInt::BatchSubInPlace (&coeff_vectors_[i], that.coeff_vectors_ [i],
253+ moduli[i]->ModParams ())
254+ .IgnoreError (); // We already checked the sizes above, and
255+ // BatchSubInPlace will only fail if its inputs have
256+ // different sizes.
229257 }
230258 return absl::OkStatus ();
231259 }
@@ -295,8 +323,10 @@ class RnsPolynomial {
295323 return output;
296324 }
297325
298- // Multiplies this polynomial by `that`.
299- // Both `this` and `that` must be in NTT form.
326+ // Multiplies this polynomial by `that`. Both `this` and `that` must be in NTT
327+ // form. May fail if the coefficient vectors of `this` and `that` are not the
328+ // same size, or the number of coefficient vectors does not match the number
329+ // of moduli. In case of failure, `this` is not modified.
300330 absl::Status MulInPlace (
301331 const RnsPolynomial& that,
302332 absl::Span<const PrimeModulus<ModularInt>* const > moduli) {
@@ -317,16 +347,29 @@ class RnsPolynomial {
317347 return absl::InvalidArgumentError (
318348 " RNS polynomial `that` must be in NTT form." );
319349 }
320-
350+ // Check all coeff vectors have the right size to catch errors before
351+ // modifying `this`.
321352 for (int i = 0 ; i < num_moduli; ++i) {
322- RLWE_RETURN_IF_ERROR (ModularInt::BatchMulInPlace (
323- &coeff_vectors_[i], that.coeff_vectors_ [i], moduli[i]->ModParams ()));
353+ if (coeff_vectors_[i].size () != that.coeff_vectors_ [i].size ()) {
354+ return absl::InvalidArgumentError (
355+ absl::StrCat (" Size of coefficient vector " , i, " does not match" ));
356+ }
357+ }
358+ for (int i = 0 ; i < num_moduli; ++i) {
359+ ModularInt::BatchMulInPlace (&coeff_vectors_[i], that.coeff_vectors_ [i],
360+ moduli[i]->ModParams ())
361+ .IgnoreError (); // We already checked the sizes above, and
362+ // BatchMulInPlace will only fail if its inputs have
363+ // different sizes.
324364 }
325365 return absl::OkStatus ();
326366 }
327367
328- // Adds the polynomial product a * b to this polynomial.
329- // Polynomials `this`, `a`, and `b` must be all in NTT form.
368+ // Adds the polynomial product a * b to this polynomial. Polynomials `this`,
369+ // `a`, and `b` must be all in NTT form. May fail if the coefficient vectors
370+ // of `this`, `a`, and `b` are not the same size, or the number of coefficient
371+ // vectors does not match the number of moduli. In case of failure, `this` is
372+ // not modified.
330373 absl::Status FusedMulAddInPlace (
331374 const RnsPolynomial& a, const RnsPolynomial& b,
332375 absl::Span<const PrimeModulus<ModularInt>* const > moduli) {
@@ -355,11 +398,22 @@ class RnsPolynomial {
355398 return absl::InvalidArgumentError (
356399 " RNS polynomial `b` must be in NTT form." );
357400 }
358-
401+ // Check all coeff vectors have the right size to catch errors before
402+ // modifying `this`.
403+ for (int i = 0 ; i < num_moduli; ++i) {
404+ if (coeff_vectors_[i].size () != a.coeff_vectors_ [i].size () ||
405+ coeff_vectors_[i].size () != b.coeff_vectors_ [i].size ()) {
406+ return absl::InvalidArgumentError (
407+ absl::StrCat (" Size of coefficient vector " , i, " does not match" ));
408+ }
409+ }
359410 for (int i = 0 ; i < num_moduli; ++i) {
360- RLWE_RETURN_IF_ERROR ( ModularInt::BatchFusedMulAddInPlace (
411+ ModularInt::BatchFusedMulAddInPlace (
361412 &coeff_vectors_[i], a.coeff_vectors_ [i], b.coeff_vectors_ [i],
362- moduli[i]->ModParams ()));
413+ moduli[i]->ModParams ())
414+ .IgnoreError (); // We already checked the sizes above, and
415+ // BatchFusedMulAddInPlace will only fail if its
416+ // inputs have different sizes.
363417 }
364418 return absl::OkStatus ();
365419 }
0 commit comments