pub struct SecureAggregation { /* private fields */ }Expand description
Secure aggregation for federated learning.
Implements privacy-preserving aggregation where the server cannot see individual client updates, only the aggregated result.
Implementations§
Source§impl SecureAggregation
impl SecureAggregation
Sourcepub fn new(threshold: usize, total_clients: usize) -> Result<Self>
pub fn new(threshold: usize, total_clients: usize) -> Result<Self>
Create a new secure aggregation instance.
Sourcepub fn generate_masks(
&self,
client_id: &str,
all_client_ids: &[String],
round: usize,
parameter_shapes: &[Vec<usize>],
) -> Result<Vec<Tensor>>
pub fn generate_masks( &self, client_id: &str, all_client_ids: &[String], round: usize, parameter_shapes: &[Vec<usize>], ) -> Result<Vec<Tensor>>
Generate client_id’s pairwise-cancelling masks for parameter_shapes
(the caller’s real model parameter shapes, in the fixed order every
client and the server agree on for this round).
Uses the standard pairwise-masking construction for secure
aggregation (Bonawitz et al.): for every OTHER id in
all_client_ids, client_id and that client derive the same seed
(via Self::pairwise_seed) and therefore the same pseudorandom
values – client_id adds them to its mask if it sorts before the
other id, subtracts them otherwise. Summing every participant’s mask
together then cancels exactly (up to floating-point rounding): each
pairwise contribution appears once with each sign. See
Self::secure_aggregate for the aggregation side and what this
construction does and does not protect against.
all_client_ids must be the exact same participant set (including
client_id itself) on every client’s call for a given round, and
parameter_shapes must be given in the same order everywhere, or the
masks will not cancel. This does not implement dropout recovery (a
full Bonawitz-style scheme additionally secret-shares each pairwise
seed so surviving clients can reconstruct a dropped client’s
contribution): if any client whose id appears in all_client_ids
does not actually submit a masked update to
Self::secure_aggregate, the missing client’s pairwise terms are
never cancelled and the aggregate is biased by exactly that client’s
unpaired contribution.
Sourcepub fn secure_aggregate(
&self,
masked_updates: HashMap<String, Vec<Tensor>>,
) -> Result<Vec<Tensor>>
pub fn secure_aggregate( &self, masked_updates: HashMap<String, Vec<Tensor>>, ) -> Result<Vec<Tensor>>
Sum (and average) masked client updates without the server ever seeing an individual client’s true update.
This assumes every masked update in masked_updates was produced by
Self::generate_masks with the same all_client_ids/round
(i.e. masked_updates.keys() matches all_client_ids exactly): the
pairwise masks then cancel exactly when summed (up to
floating-point rounding), leaving the true sum. If any participant
named in that all_client_ids set is missing from masked_updates
(a dropout), its pairwise terms are NOT cancelled and the result is
biased by that client’s unpaired mask contribution – this
implementation has no secret-sharing-based dropout recovery (see
Self::generate_masks’s doc comment). threshold only checks a
minimum client count; it does not verify the update set actually
matches a generate_masks call.
Auto Trait Implementations§
impl Freeze for SecureAggregation
impl RefUnwindSafe for SecureAggregation
impl Send for SecureAggregation
impl Sync for SecureAggregation
impl Unpin for SecureAggregation
impl UnsafeUnpin for SecureAggregation
impl UnwindSafe for SecureAggregation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more