mhostetter / galois

A performant NumPy extension for Galois fields and their applications
https://mhostetter.github.io/galois/
MIT License
295 stars 27 forks source link

Weird Arithmetic Operations Results with Arrays of Field Elements in GF(2^k) #549

Closed MohammadElMir closed 2 weeks ago

MohammadElMir commented 2 weeks ago

Assuming I am correct in using the documentation: When performing arithmetic operations with arrays of field elements in GF(2^k), the results are incorrect, even when the modulus size isn't exceeded. This leads to unexpected results, as demonstrated by the following examplein F(2^3)

import galois

Define the parameters

N = 2 q = 2 k = 3 n = 2 F = galois.GF(2**3)

Define the input shares

Rxi_dict = { 0: F([0, 0]), 1: F([0, 3]), 2: F([1, 7]) } Ryi_dict = { 0: F([0, 0]), 1: F([1, 7]), 2: F([3, 1]) }

Compute the sum of the shares

sum_rx = F([0] len(x)) sum_ry = F([0] len(y))

for i in range(1, N + 1): sum_rx += Rxi_dict[i] sum_ry += Ryi_dict[i]

Output the results

print("sum_rx:", sum_rx) print("sum_ry:", sum_ry)


Expected Output: sum_rx: [1, 2] sum_ry: [4, 0]

Actual Output: sum_rx: [1, 4] sum_ry: [2, 6]

Notice that sum_rx is computed by doing [0,0] + [0,3] + [1,7] The [0,0] + [0,3] part is working correctly, while the [0,3] + [1,7] part is evaluating to [1,4] instead of [1,2].

The same for sum_ry: [0,0] + [1,7] is working correctly but [1,7] + [3,1] is evaluating to [2,6] instead of [4,0].

I also encountered similar problems in vector subtraction where [0,1] - [2,6] was somehow evaluated to [2,7] instead of [6,3].

Is there a syntax problem from my part?

Thank you in advance :)

mhostetter commented 2 weeks ago

The [0,0] + [0,3] part is working correctly, while the [0,3] + [1,7] part is evaluating to [1,4] instead of [1,2].

What makes you think 3 + 7 = 2 in GF(2^3)? Are you expecting (3 + 7) % (2^3) = 2, because that is not the field GF(2^3). That is the ring Z(2^3).

Also, what do you think "3" represents in GF(2^3)?

In the library, "3" is the integer representation of α + 1 in GF(2)[α]. Similarly, "7" is α^2 + α + 1. The sum of these polynomials in GF(2) is α^2, which has "4" as its integer representation.

In [1]: import galois

In [2]: GF = galois.GF(2**3, repr="poly")

In [3]: a = GF(3); a
Out[3]: GF(α + 1, order=2^3)

In [4]: b = GF(7); b
Out[4]: GF(α^2 + α + 1, order=2^3)

In [5]: a + b
Out[5]: GF(α^2, order=2^3)

In [6]: GF(4)
Out[6]: GF(α^2, order=2^3)
MohammadElMir commented 2 weeks ago

Oh I'm really sorry it seems I embarassed myself. As I don't have much prior exposure to fields, I mistakenly thought that this way of calculating is only correct with multiplication and how wrong I was.

Thanks for the answer as it comes after hours of useless debugging :)