1

I am trying to transform a formula over to a finite-field equivalent of that formula.

The formula can be seen below: enter image description here

Now I have this implemented and it works correctly, but I need this in a finite-field, which means that I introduce a p, let's say p = 183269 andd take mod p but how exactly does the above formula change? Do I just mod p after i'm done calculating the formula normally?

Example:

I have the polynomial: f(x) = 1234 + 631x + 442x^2 I generated 6 random points: (x, f(x) mod p)

1. (108, 93338)
2. (413, 146507)
3. (260, 171647)
4. (819, 98605)
5. (359, 13237)
6. (894, 118490)

Now, what I want is to reconstruct 1234 given any 3 points using the above formula, but it gives me incorrect value.

here is my code:

// x_input = [108, 413, 260]
    var reconstructed float64 = 0.0

    for _, k := range x_input { 
        var y float64 = float64(points[k])
        var pr_x float64 = 1.0

        for _, l := range x_input {
            if l != k {
                var aux_k float64 = float64(k)
                var aux_l float64 = float64(l)
                pr_x *= (aux_l / (aux_l - aux_k))
            }
        }

        y *= pr_x
        reconstructed += y
    }

I'm trying to implement SSSS

EDIT

As pointed out by @user58697 I had some mistakes in my code and understanding of finite fields. I managed to rewrite my formula and it looks like this:

reconstructed := 0

    for _, k := range x_input { 
        y := points[k]
        pr_x := 1
        for _, l := range x_input {
            if l != k {
                inv := mod_inverse(l - k, p)
                pr_x *= inv
            }
        }
        y *= pr_x
        reconstructed += y
    }

    return reconstructed % p

func mod_inverse(a, p int) int {

    if a < 0 { // negative numbers are not allowed
        a = a * -1
    }

    for i := 1; i < p; i++ {
        if ((a % p) * (i % p)) % p == 1 {
            return i
        }
    }

    return p
} 

Unfortunately, it still has one or more bugs because it doesn't produce f(0)

2 Answers2

4

Do I just mod p after i'm done calculating the formula normally?

No. First you have to compute a multiplicative inverse of x[m] - x[j] modulo p. That is a tricky part to implement efficiently. The rest is indeed just multiplications and summation modulo p.

Keep in mind that floating point operations cannot work in the finite field. Everything there is precise in a sense of integers.

PS: to address a concerns about division, this is how division works in a finite field:

y/x is in fact y * z where z is a multiplicative inverse of x, that is x * z = 1 mod p. For example, let's use 7 for p. A multiplicative inverse of, say 2 is 4: 2 * 4 == 8 (== 1 mod 7). This means that 3/2 mod 7 is 3 * 4 mod 7, that is 5.

user58697
  • 7,808
  • 1
  • 14
  • 28
  • But when dividing, can it not produce floating point numbers? – Áron Pop Adorján Jun 17 '21 at 18:23
  • Thanks, and what if there is no modular multiplicative inverse for an integer? for example ```110``` and ```1832```? – Áron Pop Adorján Jun 17 '21 at 20:15
  • 1
    A multiplicative inverse of `x` modulo `p` is guaranteed to exist if `x` is coprime to `p`. If `p` is prime it is always the case. Otherwise, tough luck (it is not a _field_ anymore, BTW). That is why primes are so important in cryptography. – user58697 Jun 17 '21 at 20:25
1

You should keep it in mind that always to modulo the result after multiplying two numbers. a*b*c can cause int overflow if a<p,b<p,c<p for p=183269. And if p is larger (like 998244353), a*b can simply cause overflow. For this case, before multiplying two numbers a and b, you should cast them into int64 and modulo the result by p and finally cast it back to int.

And another point here: a is not always equivalent with -a when modulo p. Actually this is false in most cases. You should use a = (a % p + p) % p instead.

Below are the modified code that could produce the correct result (I just learned golang for this question so forgive me for possible improper code):

    reconstructed := 0
    for _, k := range x_input {
        y := points[k]
        pr_x := 1
        for _, l := range x_input {
            if l != k {
                inv := mod_inverse(l - k, p)
                // You forgot to multiply pr_x by l
                // pr_x *= inv
                pr_x = pr_x * inv % p * l % p
            }
        }
        y = y * pr_x % p
        reconstructed += y
    }

    return reconstructed % p
func mod_inverse(a, p int) int {

    if a < 0 { // negative numbers are not allowed
        // The following line is wrong! (a % p) == (a % p + p) % p when a < 0, but not -a
        // a = a * -1
        a = ((a % p) + p) % p
    }

    for i := 1; i < p; i++ {
        if ((a % p) * (i % p)) % p == 1 {
            return i
        }
    }

    // I suspect whether you should report an error here instead of returning p
    return p
}

BTW, the time complexity of mod_inverse is O(p), which can be inefficient in most cases. You can use Extended Euclidean Algorithm to calculate the multiplicative inverse of x modulo p in O(log p) time. Also, the multiplicative inverse of x modulo p is simply (x^(p-2)) % p when p is prime, and you can calculate that fast using Exponentiation by squaring. Both methods has O(log p) complexity, but the later one is easier to implement.

Sorry for my poor English. Feel free to point out my typos and mistakes.

Mivik
  • 166
  • 3