otc module

Oblivious transfer (OT) communications protocol message/response functionality implementations based on Curve25519 and the Ristretto group.

class otc.otc.common[source]

Bases: object

Wrapper class for an object that maintains a party’s state.

class otc.otc.receive[source]

Bases: otc.otc.common

Wrapper class for an object that maintains the receiving party’s state and builds receiver requests/responses.

>>> r = receive()
>>> (len(r.secret), len(r.public))
(32, 32)
query(send_public, bit)[source]

Build the initial query for two data messages (from which one must be chosen upon receipt). The returned result is the receiver’s public key, which can be shared with the sender.

Parameters
  • send_public (point) – Public key obtained from sender.

  • bit (int) – Index (0 or 1) indicating choice of message to receive.

>>> (s, r) = (send(), receive())
>>> r_public = r.query(s.public, 1)
>>> isinstance(r_public, oblivious.ristretto.point)
True

The supplied index must be either the integer 0 or the integer 1.

>>> r_public = r.query(s.public, 'abc')
Traceback (most recent call last):
  ...
TypeError: election bit must be an integer
>>> r_public = r.query(s.public, 3)
Traceback (most recent call last):
  ...
ValueError: election bit must be 0 or 1
Return type

point

elect(send_public, bit, data_zero, data_one)[source]

Choose from the two supplied data messages, decrypting the one that was chosen at the time of the query.

Parameters
  • send_public (point) – Public key obtained from sender.

  • bit (int) – Index (0 or 1) indicating choice of message to receive.

  • data_zero (Union[bytes, bytearray]) – Ciphertext corresponding to first message (i.e., at index 0) from sender.

  • data_one (Union[bytes, bytearray]) – Ciphertext corresponding to second message (i.e., at index 1) from sender.

>>> (s, r) = (send(), receive())
>>> r_public = r.query(s.public, 0)
>>> messages = s.reply(r_public, bytes([123]*16),  bytes([234]*16))
>>> list(r.elect(s.public, 0, *messages)) == ([123]*16)
True
>>> (s, r) = (send(), receive())
>>> r_public = r.query(s.public, 1)
>>> messages = s.reply(r_public, bytes([123]*16), bytes([234]*16))
>>> list(r.elect(s.public, 1, *messages)) == ([234]*16)
True

The election bit must be either the integer 0 or the integer 1.

>>> r.elect(s.public, 'abc', *messages)
Traceback (most recent call last):
  ...
TypeError: election bit must be an integer
>>> r.elect(s.public, 3, *messages)
Traceback (most recent call last):
  ...
ValueError: election bit must be 0 or 1
Return type

bytes

class otc.otc.send[source]

Bases: otc.otc.common

Wrapper class for an object that maintains the sending party’s state and builds sender requests/responses.

>>> s = send()
>>> (len(s.secret), len(s.public))
(32, 32)
reply(receive_public, data_zero, data_one)[source]

Build the response (the two data messages) that should be sent in reply to a query.

Parameters
  • receive_public (point) – Public key obtained from receiver.

  • data_zero (Union[bytes, bytearray]) – First message (i.e., at index 0) of the two from which the receiver must choose.

  • data_one (Union[bytes, bytearray]) – Second message (i.e., at index 1) of the two from which the receiver must choose.

>>> (s, r) = (send(), receive())
>>> r_public = r.query(s.public, 0)
>>> messages = s.reply(r_public, bytes([123]*16),  bytes([234]*16))
>>> all(isinstance(message, bytes) for message in messages)
True
>>> list(r.elect(s.public, 0, *messages)) == ([123]*16)
True

Messages must be bytes-like objects that have length exactly 16.

>>> rsp = s.reply(r.public, [123],  'abc')
Traceback (most recent call last):
  ...
TypeError: each message must be a bytes-like object
>>> rsp = s.reply(r.public, bytes([123]),  bytes([234]))
Traceback (most recent call last):
  ...
ValueError: each message must be of length 16
Return type

Tuple[bytes, bytes]