facebookresearch / CrypTen

A framework for Privacy Preserving Machine Learning
MIT License
1.52k stars 274 forks source link

how to conduct AND on binary shares? #510

Open mialuyao opened 2 months ago

mialuyao commented 2 months ago

I am attempting to compute the AND operation on two binary shares, but I am getting unexpected results that are not 0 or 1.

Here is my code:

@mpc.run_multiprocess(world_size=2) 
def test(x, a, b):
  x_enc, a_enc, b_enc = secret_sharing(x, a, b)
    cmp_a_x = x_enc.ge(a_enc)
    cmp_x_b = b_enc.ge(x_enc)
    cmp_a_x_share = cmp_a_x.share
    cmp_a_x_binary = BinarySharedTensor(cmp_a_x_share)
    cmp_x_b_share = cmp_x_b.share 
    cmp_x_b_binary = BinarySharedTensor(cmp_x_b_share)
    result_binary = cmp_a_x_binary & cmp_x_b_binary
    rank = comm.get().get_rank()
    crypten.print(f"\nRank {rank}:\n result: {result_binary.get_plain_text()}\n", in_order=True)

However, the result I got is:

Rank 0:
 result: 7298263103844676100

Rank 1:
 result: 7298263103844676100

The result is not in the form of 0 or 1 as I expected. Can someone explain why this is happening and how I can fix it?

Thank you for your assistance!

knottb commented 1 month ago

The code you have written will generate random values. Suppose x = 1, a = 2, b = 3:

  1. encode x, a, b into shares:

Rank 0 gets random values: (r_x, r_a, r_b) Rank 1 gets random values: (-r_x + 1, -r_a + 2, -r_b + 3)

  1. Encode the random values to binary shared tensors:

Rank 0 gets random values: (w_x, w_a, w_b) Rank 1 gets random values: (-w_x + r_x, -w_a + r_a, -w_b + r_b)

This eliminates all of the information from Rank 1, and therefore eliminates all information about x, a, and b (you will get random values)

If you are trying to get the value of (x >= a AND b >= x), the following is most efficient:

result = x_enc.ge(a_enc) * b_enc.ge(x_enc)

There are ways of doing this directly using BinarySharedTensor, but it would be more complex and involve dealing with some internals

mialuyao commented 1 month ago

Thank you for your response!

The code I provided was just an example. My core question is about performing binary operations on binary shares. I understand that MPCTensor is essentially a wrapper for BinarySharedTensor, but I am encountering unsupported operation ^ on MPCtensor and MPCTensor when attempting ^ on two binary shares. How can this issue be resolved and why?

Thank you!