-
Notifications
You must be signed in to change notification settings - Fork 37
Description
Hi,
If the array passed to ntt is a GF(2) array, then the default modulus will never satisfy the required criteria (unless the array has size 1). This is because the characteristic of the field is used, i.e., p=2, as modulus in
Line 115 in 25baec4
| modulus = type(x).characteristic |
which causes _ntt to never enter this loop to compute a valid modulus
Lines 249 to 254 in 25baec4
| if modulus is None: | |
| m = int(np.ceil(np.max(x) / size)) # The smallest m such that modulus > max(x) | |
| while not is_prime(m * size + 1): | |
| m += 1 | |
| modulus = m * size + 1 | |
| m = (modulus - 1) // size |
This is documented in the docstring, though, so perhaps I'm not understanding something here:
(...) However, if
$x$ is a$\mathrm{GF}(p)$ array, thenNonecorresponds to$p$ from the specified field.
I would expect that calling ntt should work correctly, by default, on any FieldArray. For example, I think this code should work:
from galois import GF2, ntt
ntt(GF2.Random(10))But at the moment it raises a ValueError that the user did not passed.
ValueError: Argument 'modulus' must equal m * size + 1, where 'size' is the size of the NTT transform.
A workaround, is to manually choose a valid modulus, e.g.
import numpy as np
from galois import GF2, ntt, intt
arr = GF2.Random(10)
assert np.array_equal(arr, intt(ntt(arr, modulus=11)))This also happens with other fields. For example,
from galois import GF
gf = GF(3)
arr = gf.Random(10)
ntt(gf)Commenting the two lines from ntt solves the issue for me:
Lines 114 to 115 in 25baec4
| if modulus is None and isinstance(x, FieldArray): | |
| modulus = type(x).characteristic |