lschoe / mpyc

MPyC: Multiparty Computation in Python
MIT License
367 stars 76 forks source link

Confusion on how to access share #28

Closed Elepert closed 2 years ago

Elepert commented 2 years ago

Hi, I'm trying to write a simple program that shares a number 50 with two parties and then accesses those shares and prints them out. This is my code:

from mpyc.runtime import mpc

async def main():
    async with mpc:
        secnum = mpc.SecInt()
        a = secnum(50 if mpc.pid == 0 else None)
        s = mpc.input(a, 0)
        share = await mpc.gather(s)
        print(await mpc.output(s))
        print(share)
        print(f'Share of s of party {mpc.pid}: {s.share}')

if __name__ == "__main__":
    mpc.run(main())
    mpc.run(mpc.shutdown())

My output is as follows: Party 0

50
50
Share of s of party 0: 50

Party 1

50
50
Share of s of party 1: 50

I would expect share or s.share to be the actual share that that party has, not the original value. How can I access the share for every party in plaintext? I've tried looking in the demos, but I'm still confused. Thank you!

lschoe commented 2 years ago

Hi, right, you should get identical shares of 50 for parties 0 and 1 when you run your program with two parties only. If you run it with three parties you will start to see random shares for all three parties. Note that for nontrivial shares you need to run an MPyC program with at least three parties.

Aside: you can leave out the final line mpc.run(mpc.shutdown()) because start and shutdown of the runtime are taken care of by async with mpc.

Elepert commented 2 years ago

Thank you for the information. Why is it that two parties results in identical shares? Is MPyC made for 3+ parties?

Also, this pdf on page 3 implies that the shares each party receives is between 0 and the original value. When I ran it with three parties I got -167760242016429131, -335520484032858312, and -503280726049287493. Am I not processing the shares correctly?

lschoe commented 2 years ago

Well, you can run MPyC with any number of parties m. However, an honest majority is required which means that the threshold t for secret sharing should be strictly below m/2. So, if you run with 1 or 2 parties, it follows that t must be 0, which results in a horizontal line for the Shamir polynomial. With 3 parties, we can have t=1, and that's what the default setting in MPyC will give you.

The negative values for the shares are correct. These values are modulo the prime p used for Shamir secret sharing. Since you are using secure integers, which are signed, the underlying shares are printed as signed numbers between -p/2 and p/2. If you would use secnum = mpc.SecFld(257) for instance to work with secure field elements (modulo p=257), you will see values between 0 and p-1 only, as field elements are unsigned by default.