Skip to main content

secure

Secure aggregation.

Classes

SecureShare

class SecureShare(prime_q: int = 2305843009213693951, precision: int = 10000000000):

Additive, replicated, secret sharing algorithm responsible for secure averaging.

This secret sharing implementation is 'additive' because the secret can be reconstructed by taking the sum of all the shares it is split into, and 'replicated' because each party receives more than one share.

The algorithm works as follows: 1. First every worker shares a securely generated random number (between 0 and prime_q) with every other worker such that every worker ends up with one number from every other worker. These numbers are known as shares as they will form part of the secret (the state dictionary) which will be shared. 2. The values in the state dictionary are then converted to positive integer field elements of a finite field bounded by prime_q. 3. The random numbers generated are used to compute a final share for every value in the state dictionary. This final share has the same shape as the secret state dictionary. 4. This final share is then reconstructed using the shares retrieved from the other workers. At this point, the final share from each worker is meaningless until averaged with every other state dictionary. 5. This final share is sent to the modeller where it will be averaged with the state dictionaries from all the other workers (all the while in the finite field space). 6. After averaging, the state dictionaries are finally decoded back to floating point numpy arrays.

note

The relationships between individual elements in the tensors are preserved in this implementation since our shares are scalars rather than vectors. Therefore, whilst the secret itself cannot be reconstructed, some properties of the secret can be deciphered e.g. which element is the largest/smallest, etc.

Arguments

  • prime_q: Large prime number used in secure aggregation. This should be a few orders of magnitude larger than the precision so that when we add encoded finite field elements with one another, we do not breach the limits of the finite field. A SecureShareError is raised if this occurs. Defaults to 2^61 -1 (the largest Mersenne 64 bit Mersenne prime number - for ease).
  • precision: Degree of precision for floating points in secure aggregation i.e. the number of digits after the decimal point that we want to keep. Defaults to 10^10.

Attributes

  • prime_q: Large prime number used in secure aggregation.
  • precision: Degree of precision for floating points in secure aggregation.

Ancestors

  • bitfount.federated.secure._BaseSecureShare
  • bitfount.types._BaseSerializableObjectMixIn

Variables

  • static nested_fields : ClassVar[Dict[str, Mapping[str, Any]]]

Methods


average_and_decode_state_dicts

def average_and_decode_state_dicts(    self, state_dicts: List[Dict[str, np.ndarray]],)> Dict[str, numpy.ndarray]:

Averages and decodes multiple encrypted state dictionaries.

Computes the mean of all the state_dicts before decoding the averaged result and returning it. This is called on the Modeller side after receiving the state dictionaries from all the workers.

Arguments

  • state_dicts: List of encoded state dictionaries as numpy arrays.

Returns A dictionary of averaged and decoded state dictionaries.

do_secure_aggregation

async def do_secure_aggregation(    self,    state_dict: Union[_Weights, Mapping[str, np.ndarray]],    mailbox: _InterPodWorkerMailbox,)> Dict[str, numpy.ndarray]:

Performs secure aggregation.

This is called on the Pod side before sending the state dict to the Modeller.

Arguments

  • state_dict: A dictionary of tensors or numpy arrays to be securely aggregated.
  • mailbox: A mailbox to send and receive messages from other workers.

Returns A dictionary of encoded numpy arrays.

Raises

  • SecureShareError: If finite field limit is breached. This is raised if there are not enough integers to represent all the possible floating point numbers.