Secagg Manager

Interface with the component secure aggregation element database

Attributes

Classes

BaseSecaggManager

BaseSecaggManager(db_path)

Bases: ABC

Manage a component secagg element database

Parameters:

Name Type Description Default
db_path str

path to the component's secagg database

required

Raises:

Type Description
FedbiomedSecaggError

failed to access the database

Source code in fedbiomed/common/secagg_manager.py
def __init__(self, db_path: str):
    """Constructor of the class

    Args:
        db_path: path to the component's secagg database

    Raises:
        FedbiomedSecaggError: failed to access the database
    """
    try:
        self._db = TinyDB(db_path)
        self._db.table_class = DBTable
    except Exception as e:
        errmess = f'{ErrorNumbers.FB623.value}: failed to access the database with error: {e}'
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

    self._query = Query()
    self._table = _SecaggTableSingleton(self._db).table

Functions

add abstractmethod
add(secagg_id, parties, context, experiment_id)

Add a new data entry in component secagg element database

Source code in fedbiomed/common/secagg_manager.py
@abstractmethod
def add(self, secagg_id: str, parties: List[str], context: Dict[str, int], experiment_id: str):
    """Add a new data entry in component secagg element database"""
get abstractmethod
get(secagg_id, experiment_id)

Search for a data entry in component secagg element database

Source code in fedbiomed/common/secagg_manager.py
@abstractmethod
def get(self, secagg_id: str, experiment_id: str):
    """Search for a data entry in component secagg element database"""
remove abstractmethod
remove(secagg_id, experiment_id)

Remove a data entry from component secagg element database

Source code in fedbiomed/common/secagg_manager.py
@abstractmethod
def remove(self, secagg_id: str, experiment_id: str) -> bool:
    """Remove a data entry from component secagg element database"""

SecaggDhManager

SecaggDhManager(db_path)

Bases: BaseSecaggManager

Manage the secagg table elements for Diffie Hellman components

Parameters:

Name Type Description Default
db_path str

path to the component's secagg database

required

Raises:

Type Description
FedbiomedSecaggError

failed to access the database

Source code in fedbiomed/common/secagg_manager.py
def __init__(self, db_path: str):
    """Constructor of the class

    Args:
        db_path: path to the component's secagg database

    Raises:
        FedbiomedSecaggError: failed to access the database
    """
    try:
        self._db = TinyDB(db_path)
        self._db.table_class = DBTable
    except Exception as e:
        errmess = f'{ErrorNumbers.FB623.value}: failed to access the database with error: {e}'
        logger.error(errmess)
        raise FedbiomedSecaggError(errmess)

    self._query = Query()
    self._table = _SecaggTableSingleton(self._db).table

Functions

add
add(secagg_id, parties, context, experiment_id)

Add a new data entry for a context element in the secagg table

Check that no entry exists yet for this secagg_id in the table.

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key of the entry

required
parties List[str]

list of parties participating in this secagg context element

required
experiment_id str

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

required
context Dict[str, bytes]

server key part held by this party

required
Source code in fedbiomed/common/secagg_manager.py
def add(self, secagg_id: str, parties: List[str], context: Dict[str, bytes], experiment_id: str):
    """Add a new data entry for a context element in the secagg table

    Check that no entry exists yet for this `secagg_id` in the table.

    Args:
        secagg_id: secure aggregation ID key of the entry
        parties: list of parties participating in this secagg context element
        experiment_id: ID of the experiment to which this secagg context element is attached
        context: server key part held by this party
    """
    # Save key pairs as `str`` since it is the format support by JSON. Need to convert to `base64` first
    context_json = {node_id: str(base64.b64encode(key), 'utf-8') for node_id, key in context.items()}

    self._add_generic(
        SecaggElementTypes.DIFFIE_HELLMAN,
        secagg_id,
        parties,
        {'experiment_id': experiment_id, 'context': context_json}
    )
get
get(secagg_id, experiment_id)

Search for data entry with given secagg_id

Check that there is at most one entry with this unique secagg ID.

If there is an entry for this secagg_id, check it is associated with experiment experiment_id

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key to search

required
experiment_id str

the experiment ID associated with the secagg entry

required

Returns:

Type Description
Union[dict, None]

A dict containing all values for the secagg element for this secagg_id if it exists, or None if no element exists for this secagg_id

Source code in fedbiomed/common/secagg_manager.py
def get(self, secagg_id: str, experiment_id: str) -> Union[dict, None]:
    """Search for data entry with given `secagg_id`

    Check that there is at most one entry with this unique secagg ID.

    If there is an entry for this `secagg_id`, check it is associated with experiment `experiment_id`

    Args:
        secagg_id: secure aggregation ID key to search
        experiment_id: the experiment ID associated with the secagg entry

    Returns:
        A dict containing all values for the secagg element for this `secagg_id` if it exists,
            or None if no element exists for this `secagg_id`
    """
    # Trust argument type and value check from calling class (`SecaggSetup`, `Node`)
    element = self._get_generic(secagg_id)
    self._raise_error_incompatible_requested_entry(element,
                                                   SecaggElementTypes.DIFFIE_HELLMAN,
                                                   secagg_id,
                                                   experiment_id,
                                                   'getting')

    if element:
        # Need to convert to keys as bytes
        context_bytes = {
            node_id: bytes(base64.b64decode(key)) \
                for node_id, key in element['context'].items()}
        element['context'] = context_bytes

    return element
remove
remove(secagg_id, experiment_id)

Remove data entry for this secagg_id from the secagg table

Check that the experiment ID for the table entry and the current experiment match

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key of the entry

required
experiment_id str

experiment ID of the current experiment

required

Returns:

Type Description
bool

True if an entry existed (and was removed) for this secagg_id, False if no entry existed for this secagg_id

Raises:

Type Description
FedbiomedSecaggError

database entry does not belong to experiment_id

Source code in fedbiomed/common/secagg_manager.py
def remove(self, secagg_id: str, experiment_id: str) -> bool:
    """Remove data entry for this `secagg_id` from the secagg table

    Check that the experiment ID for the table entry and the current experiment match

    Args:
        secagg_id: secure aggregation ID key of the entry
        experiment_id: experiment ID of the current experiment

    Returns:
        True if an entry existed (and was removed) for this `secagg_id`,
            False if no entry existed for this `secagg_id`

    Raises:
        FedbiomedSecaggError: database entry does not belong to `experiment_id`
    """
    # Trust argument type and value check from calling class for `secagg_id` (`SecaggSetup`, but not `Node`)
    # Don't trust `Node` for `experiment_id` type (may give `None`) but this is not an issue
    element = self._get_generic(secagg_id)
    self._raise_error_incompatible_requested_entry(element,
                                                   SecaggElementTypes.DIFFIE_HELLMAN,
                                                   secagg_id,
                                                   experiment_id,
                                                   'removing')
    return self._remove_generic(secagg_id, SecaggElementTypes.DIFFIE_HELLMAN)

SecaggServkeyManager

SecaggServkeyManager(db_path)

Bases: BaseSecaggManager

Manage the component server key secagg element database table

Parameters:

Name Type Description Default
db_path str

path to the component's secagg database

required
Source code in fedbiomed/common/secagg_manager.py
def __init__(self, db_path: str):
    """Constructor of the class

    Args:
        db_path: path to the component's secagg database
    """
    super().__init__(db_path)

Functions

add
add(secagg_id, parties, context, experiment_id)

Add a new data entry for a context element in the secagg table

Check that no entry exists yet for this secagg_id in the table.

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key of the entry

required
parties List[str]

list of parties participating in this secagg context element

required
context Dict[str, int]

server key part held by this party

required
experiment_id str

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

required
Source code in fedbiomed/common/secagg_manager.py
def add(self, secagg_id: str, parties: List[str], context: Dict[str, int], experiment_id: str):
    """Add a new data entry for a context element in the secagg table

    Check that no entry exists yet for this `secagg_id` in the table.

    Args:
        secagg_id: secure aggregation ID key of the entry
        parties: list of parties participating in this secagg context element
        context: server key part held by this party
        experiment_id: ID of the experiment to which this secagg context element is attached
    """

    # Trust argument type and value check from calling class (`SecaggSetup`, but not `Node`)
    self._add_generic(
        SecaggElementTypes.SERVER_KEY,
        secagg_id,
        parties,
        {'experiment_id': experiment_id, 'context': context}
    )
get
get(secagg_id, experiment_id)

Search for data entry with given secagg_id

Check that there is at most one entry with this unique secagg ID.

If there is an entry for this secagg_id, check it is associated with experiment experiment_id

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key to search

required
experiment_id str

the experiment ID associated with the secagg entry

required

Returns:

Type Description
Union[dict, None]

A dict containing all values for the secagg element for this secagg_id if it exists, or None if no element exists for this secagg_id

Source code in fedbiomed/common/secagg_manager.py
def get(self, secagg_id: str, experiment_id: str) -> Union[dict, None]:
    """Search for data entry with given `secagg_id`

    Check that there is at most one entry with this unique secagg ID.

    If there is an entry for this `secagg_id`, check it is associated with experiment `experiment_id`

    Args:
        secagg_id: secure aggregation ID key to search
        experiment_id: the experiment ID associated with the secagg entry

    Returns:
        A dict containing all values for the secagg element for this `secagg_id` if it exists,
            or None if no element exists for this `secagg_id`
    """

    # Trust argument type and value check from calling class (`SecaggSetup`, `Node`)
    element = self._get_generic(secagg_id)
    self._raise_error_incompatible_requested_entry(element,
                                                   SecaggElementTypes.SERVER_KEY,
                                                   secagg_id,
                                                   experiment_id,
                                                   'getting')

    return element
remove
remove(secagg_id, experiment_id)

Remove data entry for this secagg_id from the secagg table

Check that the experiment ID for the table entry and the current experiment match

Parameters:

Name Type Description Default
secagg_id str

secure aggregation ID key of the entry

required
experiment_id str

experiment ID of the current experiment

required

Returns:

Type Description
bool

True if an entry existed (and was removed) for this secagg_id, False if no entry existed for this secagg_id

Source code in fedbiomed/common/secagg_manager.py
def remove(self, secagg_id: str, experiment_id: str) -> bool:
    """Remove data entry for this `secagg_id` from the secagg table

    Check that the experiment ID for the table entry and the current experiment match

    Args:
        secagg_id: secure aggregation ID key of the entry
        experiment_id: experiment ID of the current experiment

    Returns:
        True if an entry existed (and was removed) for this `secagg_id`,
            False if no entry existed for this `secagg_id`
    """

    # Trust argument type and value check from calling class for `secagg_id` (`SecaggSetup`, but not `Node`)
    # Don't trust `Node` for `experiment_id` type (may give `None`) but this is not an issue
    element = self._get_generic(secagg_id)
    self._raise_error_incompatible_requested_entry(element,
                                                   SecaggElementTypes.SERVER_KEY,
                                                   secagg_id,
                                                   experiment_id,
                                                   'removing')
    return self._remove_generic(secagg_id, SecaggElementTypes.SERVER_KEY)

Functions