zero.aggregation package: secure aggregation

Bindings to our Rust implementation of Practical Secure Aggregation for Privacy-Preserving Machine Learning. We give an overview of this in our blog post.

In this protocol, a central server collects vectors from a certain number of clients and computes the sum, following a scheme that guarantees data privacy (see the paper for more precisions, in particular on the matter of privacy). The protocol is divided in rounds, where the server sends a message to each participant, and the participants each respond with their own message. At each round, the server awaits at list threshold messages from participants, performs a computation and then sends new messages to each participant. There are 5 rounds (see the paper for reference); at the final round the server outputs not messages but the securely aggregated sum of each user’s vector.

class zero.aggregation.SignPublicKey

A public key that is used internally to allow others to verify signatures.

Generated by gen_keypair().

Alias for bytes.

class zero.aggregation.SignSecretKey

A private key that is used internally to sign messages.

Generated by gen_keypair().

Alias for bytes.

class zero.aggregation.PublicKeysWrapper

An interface to build a dictionnary that maps user ids to SignPublicKey’s.

insert(u, pk)

Registers a public key for a user id.

Parameters:
class zero.aggregation.UserWrapper

Wraps the internal User object.

This handles all the client side of the protocol. The session parameters and the data to share are given at the creation of the UserWrapper, then it suffices to respond to the server’s messages.

__new__(id, threshold, sign_pk, sign_sk, vec, others_sign_pks)
Parameters:
  • id (int) – The identifier of this user

  • threshold (int) – The minimum number of user that must participate for the aggregation to continue

  • sign_pk (SignPublicKey) – This user’s public key

  • sign_sk (SignSecretKey) – This user’s private key

  • vec (list[int]) – The vector to send – kept confidential by the protocol (see the paper for more information)

  • other_sign_pks (PublicKeysWrapper) – The public keys of all the users who participate in the aggregation

Return type:

UserWrapper

round(input)

This batteries-included function handles the client side of the secure aggregation protocol. It expects a message from the server and outputs a new message that must be sent to the server.

Parameters:

input (bytes) – The message that the server sent

Return type:

bytes

Raises:

IOError – If the input is invalid, or a tamper is detected – the client is then put in an error state

serialize_state()

Writes the state of this object to a string. The data is formatted in JSON (which can be helpful for storages that optimize JSON data, like PostgreSQL). However the exact contents of the serialized object are not specified.

The output contains secrets so do not render the output of this function public.

Return type:

str

recover_state(state)

Recovers the state that has been serialized by serialize_state().

Parameters:

state (str) – The string that was given by a previous call to serialize_state()

class zero.aggregation.ServerOutputWrapper

The server can output two sorts of things after a round: either messages for each participant, or, after the last round, the result vector.

This class represents these outputs, and is essentially an ad-hoc implementation of a sum type.

is_messages()

Did the server output messages?

Return type:

bool

is_vector()

Did the server output a vector?

Return type:

bool

get_messages()

If the server did output messages, returns a dictionary that maps each user identifier to the message that must be sent to that user.

Return type:

Dict[int, bytes]

Raises:

IOError – If the server actually outputted a vector.

get_vector()

If the server did output a vector, returns that vector.

Return type:

list[int]

Raises:

IOError – If the server actually outputted messages.

class zero.aggregation.ServerWrapper
__new__(cls, threshold: int, vec_len: int) 'ServerWrapper': ...
Parameters:
  • threshold (int) – The minimum number of user that must participate for the aggregation to continue

  • vec_len (int) – The dimension of the vectors that will be sent by the users

recv(id, input)

Signals that a message was sent by a user.

Must be called before round().

Parameters:
  • id (int) – The user’s identifier

  • input (bytes) – The message

Raises:

IOError – If the input is invalid – but the server isn’t in an error state after that

round()

Computes, based on the messages that were received for this round through recv(), the result of the current round (either new messages for the users, or the computed sum).

Return type:

ServerOutputWrapper

Raises:

IOError – If less than threshold messages have been received, or if the received data is incoherent – the server is put in an error state after that

serialize_state()

Writes the state of this object to a string. The data is formatted in JSON (which can be helpful for storages that optimize JSON data, like PostgreSQL). However the exact contents of the serialized object are not specified.

As opposed to UserWrapper.serialize_state(), the output doesn’t contain secrets, so it doesn’t need to be specially protected.

Return type:

str

recover_state(state)

Recovers the state that has been serialized by serialize_state().

Parameters:

state (str) – The string that was given by a previous call to serialize_state()

zero.aggregation.round0_msg()

Returns the message that must be given to each user for the first round.

Return type:

bytes

zero.aggregation.gen_keypair()

Generates a pair of keys that will be used internally to verify that the participants can be trusted.

See the paper for more information.

Return type:

Tuple[SignPublicKey, SignSecretKey]