Secagg

Classes

SecaggBaseSetup

SecaggBaseSetup(researcher_id, secagg_id, parties, experiment_id=None)

Bases: ABC

Sets up a Secure Aggregation context element on the node side.

Parameters:

Name Type Description Default
researcher_id str

ID of the researcher that requests setup

required
secagg_id str

ID of secagg context element for this setup request

required
experiment_id Union[str, None]

ID of the experiment to which this secagg context element is attached (empty string if no attached experiment)

None
parties List[str]

List of parties participating in the secagg context element setup

required

Raises:

Type Description
FedbiomedSecaggError

bad argument type or value

Source code in fedbiomed/node/secagg/_secagg_setups.py
def __init__(
        self,
        researcher_id: str,
        secagg_id: str,
        parties: List[str],
        experiment_id: Union[str, None] = None,
):
    """Constructor of the class.

    Args:
        researcher_id: ID of the researcher that requests setup
        secagg_id: ID of secagg context element for this setup request
        experiment_id: ID of the experiment to which this secagg context element
            is attached (empty string if no attached experiment)
        parties: List of parties participating in the secagg context element setup

    Raises:
        FedbiomedSecaggError: bad argument type or value
    """
    errmess: str = ''
    if len(parties) < self._min_num_parties:
        errmess = f'{ErrorNumbers.FB318.value}: bad parameter `parties` : {parties} : need  ' \
            f'at least {self._min_num_parties} parties for secure aggregation, but got {len(parties)}'

    if researcher_id is None:
        errmess = f'{ErrorNumbers.FB318.value}: argument `researcher_id` must be a non-None value'

    if errmess:
        # if one of the above condition is met, raise error
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

    # assign argument values
    self._researcher_id = researcher_id
    self._secagg_id = secagg_id
    self._experiment_id = experiment_id
    self._parties = parties
    self._element: SecaggElementTypes = None

    # to be set in subclasses
    self._secagg_manager: SecaggManager = None

Attributes

element property
element

Getter for secagg context element type

Returns:

Type Description
Enum

secagg context element name

experiment_id property
experiment_id

Getter for experiment_id

Returns:

Type Description
Union[str, None]

ID of the experiment to which this secagg context element is attached (empty string if no attached experiment)

researcher_id property
researcher_id

Getter for researcher_id

Returns:

Type Description
str

researcher unique ID

secagg_id property
secagg_id

Getter for secagg_id

Returns:

Type Description
str

secagg context element unique ID

Functions

setup
setup()

Set up a secagg context element.

Returns:

Type Description
dict

message to return to the researcher after the setup

Source code in fedbiomed/node/secagg/_secagg_setups.py
def setup(self) -> dict:
    """Set up a secagg context element.

    Returns:
        message to return to the researcher after the setup
    """
    # Caveat: we don't test if a context exists for this `secagg_id` eg
    #   context = self._secagg_manager.get(self._secagg_id, self._experiment_id)
    #
    # In the case of (possibly) previous secagg setup succeeded on some nodes (which thus
    # created a context) and failed on some nodes, negotiating only on previously failed nodes
    # would result in either negotiation delay/timeouts.
    # Nevertheless, it finally fails as new context cannot be saved on nodes where it already exists.
    # Another `secagg_id` should be used or partially existing entry be cleaned from database
    try:
        self._setup_specific()
    except FedbiomedError as e:
        logger.debug(f"{e}")
        return self._create_secagg_reply("Can not setup secure aggregation context "
                                         f"on node for {self._secagg_id}.", False)
    except Exception as e:
        logger.debug(f"{e}")
        return self._create_secagg_reply('Unexpected error occurred please '
                                         'report this to the node owner', False)

    return self._create_secagg_reply('Context element was successfully created on node', True)

SecaggBiprimeSetup

SecaggBiprimeSetup(researcher_id, secagg_id, parties, experiment_id=None)

Bases: SecaggMpspdzSetup

Sets up a biprime Secure Aggregation context element on the node side.

Parameters:

Name Type Description Default
researcher_id str

ID of the researcher that requests setup

required
secagg_id str

ID of secagg context element for this setup request

required
experiment_id None

unused argument

None
parties List[str]

List of parties participating to the secagg context element setup

required

Raises:

Type Description
FedbiomedSecaggError

bad argument type or value

Source code in fedbiomed/node/secagg/_secagg_setups.py
def __init__(
        self,
        researcher_id: str,
        secagg_id: str,
        parties: List[str],
        experiment_id: None = None):

    """Constructor of the class.

    Args:
        researcher_id: ID of the researcher that requests setup
        secagg_id: ID of secagg context element for this setup request
        experiment_id: unused argument
        parties: List of parties participating to the secagg context element setup

    Raises:
        FedbiomedSecaggError: bad argument type or value
    """
    super().__init__(researcher_id, secagg_id, parties, None)

    self._element = SecaggElementTypes.BIPRIME
    self._secagg_manager = BPrimeManager

    if experiment_id is not None:
        errmess = f'{ErrorNumbers.FB318.value}: bad parameter `experiment_id` must be None'
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

SecaggDHSetup

SecaggDHSetup(researcher_id, secagg_id, parties, experiment_id, grpc_client, pending_requests, controller_data)

Bases: SecaggBaseSetup

Sets up a server key Secure Aggregation context element on the node side.

Parameters:

Name Type Description Default
researcher_id str

ID of the researcher that requests setup

required
secagg_id str

ID of secagg context element for this setup request

required
experiment_id str

ID of the experiment to which this secagg context element is attached

required
parties List[str]

List of parties participating to the secagg context element setup

required
grpc_client GrpcController

object managing the communication with other components

required
pending_requests EventWaitExchange

object for receiving overlay node to node messages

required
controller_data EventWaitExchange

object for passing data to the node controller

required

Raises:

Type Description
FedbiomedSecaggError

bad argument type or value

Source code in fedbiomed/node/secagg/_secagg_setups.py
def __init__(
        self,
        researcher_id: str,
        secagg_id: str,
        parties: List[str],
        experiment_id: str,
        grpc_client: GrpcController,
        pending_requests: EventWaitExchange,
        controller_data: EventWaitExchange,
):
    """Constructor of the class.

    Args:
        researcher_id: ID of the researcher that requests setup
        secagg_id: ID of secagg context element for this setup request
        experiment_id: ID of the experiment to which this secagg context element is attached
        parties: List of parties participating to the secagg context element setup
        grpc_client: object managing the communication with other components
        pending_requests: object for receiving overlay node to node messages
        controller_data: object for passing data to the node controller

    Raises:
        FedbiomedSecaggError: bad argument type or value
    """
    super().__init__(researcher_id, secagg_id, parties, experiment_id)

    self._element = SecaggElementTypes.DIFFIE_HELLMAN
    self._secagg_manager = DHManager
    self._grpc_client = grpc_client
    self._pending_requests = pending_requests
    self._controller_data = controller_data

    if not self._experiment_id or not isinstance(self._experiment_id, str):
        errmess = f'{ErrorNumbers.FB318.value}: bad parameter `experiment_id` must be a non empty string'
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

SecaggRound

SecaggRound(secagg_arguments, experiment_id)

This class wraps secure aggregation schemes

Attributes:

Name Type Description
scheme _SecaggSchemeRound | None

Secure aggregation scheme

use_secagg bool

True if secure aggregation is activated for round

Source code in fedbiomed/node/secagg/_secagg_round.py
def __init__(
    self,
    secagg_arguments: Dict[str, Any],
    experiment_id: str
) -> None:
    """Constructor of the class"""

    self.use_secagg: bool = False
    self.scheme: _SecaggSchemeRound | None = None

    if not secagg_arguments and environ["FORCE_SECURE_AGGREGATION"]:
        raise FedbiomedSecureAggregationError(
            f"{ErrorNumbers.FB318.value}: Node requires to apply secure aggregation but "
            f"training request does not define it.")

    if secagg_arguments:
        if not environ["SECURE_AGGREGATION"]:
            raise FedbiomedSecureAggregationError(
                f"{ErrorNumbers.FB318.value} Requesting secure aggregation while "
                "it's not activated on the node."
            )

        sn = secagg_arguments.get('secagg_scheme')

        if sn is None:
            raise FedbiomedSecureAggregationError(f"{ErrorNumbers.FB318.value}: Secagg scheme value missing in "
                                                  "the argument `secagg_arguments`")
        try:
            _scheme = SecureAggregationSchemes(sn)
        except ValueError as e:
            raise FedbiomedSecureAggregationError(
                f"{ErrorNumbers.FB318.value}: Bad secagg scheme value in train request: {sn}"
            ) from e

        self.scheme = SecaggRound.element2class[_scheme.value](secagg_arguments, experiment_id)
        self.use_secagg = True

Attributes

element2class class-attribute instance-attribute
element2class = {value: _JLSRound, value: _LomRound}
scheme instance-attribute
scheme = None
use_secagg instance-attribute
use_secagg = False

SecaggServkeySetup

SecaggServkeySetup(researcher_id, secagg_id, parties, experiment_id)

Bases: SecaggMpspdzSetup

Sets up a server key Secure Aggregation context element on the node side.

Parameters:

Name Type Description Default
researcher_id str

ID of the researcher that requests setup

required
secagg_id str

ID of secagg context element for this setup request

required
experiment_id str

ID of the experiment to which this secagg context element is attached

required
parties List[str]

List of parties participating to the secagg context element setup

required

Raises:

Type Description
FedbiomedSecaggError

bad argument type or value

Source code in fedbiomed/node/secagg/_secagg_setups.py
def __init__(
        self,
        researcher_id: str,
        secagg_id: str,
        parties: List[str],
        experiment_id: str,
):
    """Constructor of the class.

    Args:
        researcher_id: ID of the researcher that requests setup
        secagg_id: ID of secagg context element for this setup request
        experiment_id: ID of the experiment to which this secagg context element is attached
        parties: List of parties participating to the secagg context element setup

    Raises:
        FedbiomedSecaggError: bad argument type or value
    """
    super().__init__(researcher_id, secagg_id, parties, experiment_id)

    self._element = SecaggElementTypes.SERVER_KEY
    self._secagg_manager = SKManager

    if not self._experiment_id or not isinstance(self._experiment_id, str):
        errmess = f'{ErrorNumbers.FB318.value}: bad parameter `experiment_id` must be a non empty string'
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

SecaggSetup

SecaggSetup(element, **kwargs)

Factory class for instantiating any type of node secagg context element setup class

Source code in fedbiomed/node/secagg/_secagg_setups.py
def __init__(self, element: int, **kwargs):
    """Constructor of the class
    """
    self._element = element
    self.kwargs = kwargs

Attributes

element2class class-attribute instance-attribute
element2class = {name: SecaggServkeySetup, name: SecaggBiprimeSetup, name: SecaggDHSetup}
kwargs instance-attribute
kwargs = kwargs