Files
sdk/python/blyss/blyss_lib.py
Neil Movva 9604fd30e1 [BLY-66] direct upload pparams (#28)
* bucket check and async setup
clients perform direct setup by default

* (python) more consistent json for internal api

all requests and response are JSON.
all binary payloads are explicitly encoded as base64
within api.py, and decoded back to bytes before leaving api.py.
User-facing code, e.g. bucket.py and bucket_service.py,
should not see base64 wrangling.

* Support async for all ops

refactor api.py to be async-first
use new asyncio loops to support non-async interface;
cannot call non-async methods from async context

* [js] update client to work with unified service
bump both versions to 0.2.1
disable npm/pypi publish except on manual workflow run

* disable request compression

* fix workflow tests

update standalone Spiral test server to use new JSON interface
2023-09-11 16:55:35 -07:00

112 lines
3.5 KiB
Python

"""BlyssLib
INTERNAL
This Python module is the *only* code that interfaces with
the compiled Rust code.
"""
from typing import Any, Optional
from .seed import seed_from_string
from . import blyss, seed # type: ignore
# NB: There are many "type: ignore"s on purpose. Type information
# for the maturin output is difficult to include nicely, so we just wrap it here.
class BlyssLib:
"""
A class wrapping a bytes-for-bytes cryptographic interface for the Blyss service.
"""
def generate_keys(self):
"""Generates the clients keys. Skips public parameter generation.
Args:
generate_public_parameters (bool): Whether the client should generate
additional public parameters.
"""
blyss.generate_keys( # type: ignore
self.inner_client,
seed_from_string(self.secret_seed),
False,
)
def generate_keys_with_public_params(self) -> bytes:
"""Generates the clients keys, including public parameters.
This can take a long time, so prefer `generate_keys` when possible.
Returns:
bytes: The generated public parameters, if requested.
"""
r = blyss.generate_keys(
self.inner_client,
seed_from_string(self.secret_seed),
True,
)
return bytes(r)
def get_row(self, key: str) -> int:
"""Gets the target row in the database for a given key.
Args:
key (str): The key to find the row of.
Returns:
int: The row corresponding to the given key.
"""
return blyss.get_row(self.inner_client, key) # type: ignore
def generate_query(self, uuid: str, row_idx: int) -> bytes:
"""Generates a query for the given row index.
Args:
uuid (str): The UUID of public parameters that have already been uploaded to the server.
row_idx (int): The index of the target row of the query.
Returns:
bytes: The raw bytes the client should send to the server as its query.
"""
return bytes(blyss.generate_query(self.inner_client, uuid, row_idx)) # type: ignore
def decode_response(self, response: bytes) -> bytes:
"""Decodes the PIR response to plaintext, using the client's secrets.
Args:
response (bytes): The raw PIR response from the server.
Returns:
bytes: The plaintext data in the response.
"""
return bytes(blyss.decode_response(self.inner_client, response)) # type: ignore
def extract_result(self, key: str, data: bytes) -> Optional[bytes]:
"""Extracts the value for a given key, given the plaintext data from a response.
Args:
key (str): The key the client is looking up.
data (bytes): The plaintext data from the PIR response.
Returns:
bytes: The plaintext data corresponding to the given key, or None if the key was not found.
"""
r = blyss.extract_result(self.inner_client, key, data)
if r is None:
return None
else:
return bytes(r)
def __init__(self, params: str, secret_seed: str):
"""Initializes a new BlyssLib instance.
Args:
params (str): The set of JSON parameters for the underlying PIR scheme.
secret_seed (str): A base64-encoded secret seed that is used to derive all client secrets.
"""
self.inner_client: Any = blyss.initialize_client(params) # type: ignore
self.secret_seed = secret_seed