Less Than Zero Comparison

Here we demonstrate testing a secret-shared array elementwise to see if the values are less than zero. The resulting secret shared array will be the same shape as the input, containing \(1\) where the input is less than zero, and \(0\) where it is not. Note that we use the Boolean encoding when we reveal the output because the default FixedPoint encoding would produce unexpected results.

Note that this comparison is roughly three times faster than using Less Than Comparison with \(0\) as the second operand.

In this example, we will compare the vector \([2, -1.5, 0]\) to zero, which should return \([0, 1, 0]\):

[1]:
import logging

import numpy

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

logging.basicConfig(level=logging.INFO)

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

    a = numpy.array([2, -1.5, 0]) if communicator.rank == 0 else None

    log.info(f"Player {communicator.rank} secret: {a}", src=0)

    a_share = protocol.share(src=0, secret=a, shape=(3,))
    less_zero_share = protocol.less_zero(a_share)
    less_zero = protocol.reveal(less_zero_share, encoding=Boolean())

    log.info(f"Player {communicator.rank} result: {less_zero}")

SocketCommunicator.run(world_size=3, fn=main);
INFO:root:Player 0 secret: [ 2.  -1.5  0. ]
INFO:root:Player 0 result: [False  True False]
INFO:root:Player 1 result: [False  True False]
INFO:root:Player 2 result: [False  True False]