Random Bit Generation
Here we briefly demonstrate generating collections of secret shared uniform random bits, a primitive often useful in the construction of more complex protocols.
We provide an instance of numpy.random.Generator to seed the process along with the required number of bits. The result is a secret shared vector containing the requested bits in big-endian order, and the secret shared integer value of the bits. Since neither result was encoded from a real value, we use the Bits encoding to reveal the bits, and Identity to reveal the secret.
In this example we call the function several times using four bits and print the outputs for verification.
[1]:
import logging
import numpy
from cicada.additive import AdditiveProtocolSuite
from cicada.communicator import SocketCommunicator
from cicada.encoding import Bits, Identity
from cicada.logger import Logger
logging.basicConfig(level=logging.INFO)
def main(communicator):
log = Logger(logging.getLogger(), communicator)
protocol = AdditiveProtocolSuite(communicator)
generator = numpy.random.default_rng(seed=1234)
for index in range(3):
log.info("*" * 40, src=0)
bits_share, secret_share = protocol.random_bitwise_secret(generator=generator, bits=4)
bits = protocol.reveal(bits_share, encoding=Bits())
secret = protocol.reveal(secret_share, encoding=Identity())
log.info(f"Player {communicator.rank} bits: {bits} secret: {secret}")
SocketCommunicator.run(world_size=3, fn=main);
INFO:root:****************************************
INFO:root:Player 0 bits: [1 1 1 0] secret: 14
INFO:root:Player 1 bits: [1 1 1 0] secret: 14
INFO:root:Player 2 bits: [1 1 1 0] secret: 14
INFO:root:****************************************
INFO:root:Player 0 bits: [0 1 0 0] secret: 4
INFO:root:Player 1 bits: [0 1 0 0] secret: 4
INFO:root:Player 2 bits: [0 1 0 0] secret: 4
INFO:root:****************************************
INFO:root:Player 0 bits: [0 0 1 0] secret: 2
INFO:root:Player 1 bits: [0 0 1 0] secret: 2
INFO:root:Player 2 bits: [0 0 1 0] secret: 2
See also