tinybook module
Minimal pure-Python library that demonstrates a basic workflow for an encrypted order book by leveraging a secure multi-party computation (MPC) protocol.
- class tinybook.tinybook.node[source]
Bases:
objectData structure for maintaining the information associated with a node and performing node operations.
Suppose that a workflow is supported by three parties. The
nodeobjects would be instantiated locally by each of these three parties.>>> nodes = [node(), node(), node()]
The preprocessing workflow that the nodes must execute can be simulated using the
preprocessfunction. It is assumed that all permitted prices are integers greater than or equal to0and strictly less than a fixed maximum value. The number of distinct prices must be supplied to thepreprocessfunction.>>> preprocess(nodes, prices=16)
A request must be submitted for the opportunity to submit an order. The clients can create
requestinstances for this purpose. Below, two clients each create their request.>>> request_ask = request.ask() >>> request_bid = request.bid()
Each client can deliver their request to each node, and each node can then locally use its
masksmethod to generate masks that can be returned to the requesting client.>>> masks_ask = [node.masks(request_ask) for node in nodes] >>> masks_bid = [node.masks(request_bid) for node in nodes]
Each client can then generate locally an
orderinstance (i.e., a masked representation of the order).>>> order_ask = order(masks_ask, 4) >>> order_bid = order(masks_bid, 9)
Each client can broadcast its masked order to all the nodes. Each node can locally assemble these as they arrive. Once a node has received both masked orders, it can determine its shares of the overall outcome using the
outcomemethod.>>> shares = [node.outcome(order_ask, order_bid) for node in nodes]
The overall outcome can be reconstructed from the shares by the workflow operator using the
revealfunction. The outcome is eitherNone(if the bid price does not equal or exceed the ask price) or arangeinstance representing the bid-ask spread (where for arangeinstancer, the ask price ismin(r)and the bid price ismax(r)).>>> reveal(shares) range(4, 10) >>> min(reveal(shares)) 4 >>> max(reveal(shares)) 9
In the example below, the bid price does not exceed the price of the ask.
>>> order_ask = order(masks_ask, 11) >>> order_bid = order(masks_bid, 7) >>> shares = [node.outcome(order_ask, order_bid) for node in nodes] >>> reveal(shares) is None True
- class tinybook.tinybook.request[source]
-
Data structure for representing a request to submit an order. A request can be submitted to each node to obtain corresponding masks for an order.
Instances should only be constructed using the
request.askandrequest.bidmethods.
- class tinybook.tinybook.order(masks, price)[source]
Bases:
listData structure for representing an order that can be broadcast to nodes.
- Parameters
Suppose masks have already been obtained from the nodes via the steps below.
>>> nodes = [node(), node(), node()] >>> preprocess(nodes, prices=16) >>> price = 7 >>> masks = [node.masks(request.ask()) for node in nodes]
This method can be used to mask the order (in preparation for broadcasting it to the nodes).
>>> isinstance(order(masks, price), order) True
- tinybook.tinybook.preprocess(nodes, prices)[source]
Simulate a preprocessing workflow among the supplied nodes for a workflow that supports the specified number of distinct prices (where prices are assumed to be integers greater than or equal to
0and strictly less than the valueprices).- Parameters
The example below performs a preprocessing workflow involving three nodes.
>>> nodes = [node(), node(), node()] >>> preprocess(nodes, prices=16)
- tinybook.tinybook.reveal(shares)[source]
Reconstruct the overall workflow outcome (representing the bid-ask spread) from the shares obtained from each node.
- Parameters
shares (
List[List[modulo]]) – Shares of overall outcome (where each share is a list in which each entry corresponds to one of the permitted price values).
Suppose the shares below are returned from the three nodes in a workflow.
>>> from modulo import modulo >>> p = 340282366920938463463374607431768196007 >>> shares = [ ... [ ... modulo(191698724691236883130020433754311906556, p), ... modulo(192553930942215974753329735796719934503, p), ... modulo(96579911660242665783999103846211668558, p) ... ], ... [ ... modulo(203604595735418244883008588068488824844, p), ... modulo(213569286850324010515175569194586924260, p), ... modulo(97156260151248494516609766219626086128, p) ... ], ... [ ... modulo(285261413415221798913720193040735660613, p), ... modulo(274441516049336941658243909872229533251, p), ... modulo(146546195109447303162765737365930441321, p) ... ] ... ]
This method combines such shares into an overall workflow outcome by reconstructing the individual components and extracting the bid-ask spread (if possible). In particular, the output is either
None(if the bid price does not equal or exceed the ask price) or arangeinstance representing the bid-ask spread (where for arangeinstancer, the ask price ismin(r)and the bid price ismax(r)).>>> reveal(shares) range(1, 3)