Logical Exclusive Or

In this example, we will compute the elementwise logical XOR of secret shared bits.

Note that the secret inputs to logical_xor() must be the field values \(0\) or \(1\), producing similar outputs. We use the Bits encoding for our inputs and outputs because the default FixedPoint encoding would produce unexpected results.

[1]:
import logging

import numpy

from cicada.additive import AdditiveProtocolSuite
from cicada.communicator import SocketCommunicator
from cicada.encoding import Bits
from cicada.logging import Logger

logging.basicConfig(level=logging.INFO)

def main(communicator):
    log = Logger(logging.getLogger(), communicator)
    protocol = AdditiveProtocolSuite(communicator)

    x = numpy.array([0, 1, 0, 1]) if communicator.rank == 0 else None
    y = numpy.array([0, 0, 1, 1]) if communicator.rank == 1 else None

    x_share = protocol.share(src=0, secret=x, shape=(4,), encoding=Bits())
    y_share = protocol.share(src=1, secret=y, shape=(4,), encoding=Bits())
    xor_share = protocol.logical_xor(x_share, y_share)
    xor = protocol.reveal(xor_share, encoding=Bits())

    log.info(f"Player {communicator.rank} x: {x}", src=0)
    log.info(f"Player {communicator.rank} y: {y}", src=1)
    log.info(f"Player {communicator.rank} x xor y: {xor}")

SocketCommunicator.run(world_size=3, fn=main);
INFO:root:Player 0 x: [0 1 0 1]
INFO:root:Player 1 y: [0 0 1 1]
INFO:root:Player 0 x xor y: [0 1 1 0]
INFO:root:Player 1 x xor y: [0 1 1 0]
INFO:root:Player 2 x xor y: [0 1 1 0]

See also

Logical Not