RFC-0011 — Secure Aggregation Protocol¶
| RFC | 0011 |
| Title | Secure Aggregation Protocol |
| Slug | secure-aggregation |
| Status | Accepted |
| Track | Standards |
| Authors | @AbdelStark |
| Created | 2026-06-02 |
| Target milestone | v0.2 (simulated, single-process) → v0.3 (real multi-party over a network boundary) |
| Area | area:aggregation |
| Requires | RFC-0003 (the round that invokes this), RFC-0012 (the noise added before masking), RFC-0013 (the round state machine that drives dropout recovery) |
| Defers to | RFC-0013 (transport, key-exchange channel, state-machine handling of SecureAggregationError) |
Implementation status (2026-07-24 — end-to-end integration blocked). The pairwise-mask primitive, fixed-point simulated-sum harness, and software-simulated TEE backend have direct tests. They are not yet the input path used by the live coordinator.
Phase3CoordinatorServiceaccepts and stores an unmasked per-participantPseudoGradient.delta;Coordinator.try_round()consumes those plaintext deltas and commits the outer step beforebuild_phase3_aggregation_privacy_report()runs. The simulated/TEE sum produced by that report is therefore a post-commit equivalence cross-check, not the update consumed byOuterOptimizer. Current reports emitbackend_status=post_commit_cross_checkandsecure_sum_consumed=false; schema-v1secure_sum/truerows are normalized to that conservative meaning by the current reader without rewriting the historical artifact. The masking selection records an explicit fallback. Until the coordinator consumes only a backend-produced sum, this RFC's individual-update-confidentiality guarantee is an intended contract, not current runtime behavior. Historical Phase 3secure_sumrows are primitive/cross-check evidence under this boundary.
Summary¶
This RFC specifies the intended protocol by which the coordinator obtains the sum Σ_c Δ_c of
participant pseudo-gradients while
learning nothing about any individual Δ_c. It owns the cryptographic mechanics of the
secure-aggregate step (step 5 of the round in
RFC-0003 §2); the round
requirement — "the coordinator MUST learn only Σ_c Δ_c" and the two protocol-level constraints
(dropout robustness, determinism preservation) — lives in
RFC-0003 §5.
Two backend contracts are specified, and their implementations are testable and config-selectable.
Coordinator integration remains blocked as stated above. The default protocol design is a
pairwise-mask protocol (Bonawitz-style): each ordered participant pair agrees a shared seed, derives a
pseudo-random mask vector that is added by one party and subtracted by the other, so masks cancel
exactly in the sum while each individual masked update is computationally hiding. Self-masks plus
threshold (Shamir) secret sharing of every mask seed make the round dropout-robust: it completes if
at least a configured threshold t_agg of participants survive. The alternative backend is a
TEE-attested aggregator that receives plaintext Δ_c inside an attested enclave and emits only the
sum. The masking backend introduces no nondeterminism into the revealed sum (masks cancel exactly
over the integer field, then the deterministic outer step runs unchanged,
INV-AGG-DETERMINISM). Participant-specific gauge alignment and re-difference happen first
(INV-ALIGN-BEFORE-RELEASE); DP noise (RFC-0012) is then added
per participant before masking; int8 quantization
(RFC-0003 §6) is orthogonal and
applied before masking.
The guarantee and residual-trust statement this RFC backs are reproduced by the security model (06 §4 Secure-aggregation guarantee); the dropout failure mode and its fields are catalogued in 04 §Secure-aggregation dropout.
Motivation¶
The federated round releases one PseudoGradient per participant per round
(RFC-0003 §3). A single participant's
Δ_c is far more revealing about that silo's sovereign data than the population sum: it is the
direction the model would move to fit one silo's trajectories, and gradient-inversion attacks can
reconstruct training inputs from individual updates. Even with per-participant differential privacy
(RFC-0012), an honest-but-curious coordinator that observes the
cleartext per-participant Δ_c defeats the project's residency posture (INV-RESIDENCY,
01 §5 Trust boundaries): raw data does not cross the boundary, but a
sufficiently informative function of it would.
Secure aggregation closes this: the aggregator obtains only Σ_c Δ_c, which is exactly the input the
outer Nesterov step uses (RFC-0003 §2 step 7),
so revealing the sum loses no information the protocol needs. It also keeps the Phase-2
aggregation-correctness proof cheap: the anchored frame (RFC-0002 §4)
keeps aggregation a near-linear weighted average, and masking does not perturb that linearity — masks
cancel and the revealed sum is bit-for-bit the plaintext sum, so the public-recomputation / STARK target
is unchanged (RFC-0006 §2).
The hard requirement is dropout robustness without breaking determinism. Participants churn (compute
heterogeneity, network partitions,
RFC-0003 §6); a naive pairwise-mask
scheme stalls when any masked-but-not-cancelled party vanishes mid-round. The protocol must recover the
sum over the surviving set deterministically, or fail closed with SecureAggregationError.
Goals¶
- Specify the pairwise-mask backend: key agreement, mask derivation from a shared seed, the integer
fixed-point encoding over which masks cancel exactly, the masked-update wire format, and the
reconstruction of
Σ_c Δ_c. - Specify dropout robustness: self-masks plus threshold (Shamir) secret sharing of mask seeds and
self-mask seeds, so a round completes iff at least
t_aggparticipants survive; belowt_aggraisesSecureAggregationError. - State the security property precisely (the aggregator's view is computationally indistinguishable from
learning only
Σ_c Δ_cand the participant set) and its honest assumptions (the collusion bound). - Pin the interaction with gauge correction (participant-specific alignment before every release
transform), with DP (noise before masking, per participant), with the deterministic outer step
(masks cancel exactly; no nondeterminism in the revealed sum,
INV-AGG-DETERMINISM), and with int8 quantization (orthogonal; applied before masking). - Specify a TEE-attested aggregator as a second supported, config-selectable backend, with its distinct trust assumption stated.
- Enumerate the failure modes (dropout below threshold, mask non-cancellation, key-agreement failure, attestation failure) and the typed error each raises (04 — Error Model; taxonomy: conventions §6).
Non-Goals¶
- The federated round lifecycle, the
PseudoGradientcontract, and the outer Nesterov step. Owned by RFC-0003. - The differential-privacy mechanism, the
(ε,δ)accountant, and joint calibration. Owned by RFC-0012; this RFC fixes the downstream ordering (aligned re-difference before clip/noise, then noise before mask). - The transport (gRPC vs HTTP/REST), the key-exchange channel, and the state-machine handling of a
raised
SecureAggregationError(retry vs abort). Owned by RFC-0013. - The Phase-2 aggregation-correctness STARK. Owned by RFC-0006; this RFC only preserves the determinism and linearity that proof depends on.
- The dataset-commitment binding (
Commitmentmessage,R_c). Owned by RFC-0014; secure aggregation operates ondelta, the commitment travels alongside in the clear. - A defense against a coordinator colluding with
C-1participants (the standard collusion bound is inherited, not removed in Phase 1 — see Drawbacks).
Proposed Design¶
The aggregation subsystem lives in lensemble.aggregation (secure_agg.py, masking.py,
conventions §1). It exposes a backend-agnostic
aggregator interface. Under the intended round contract
(RFC-0003 §2), each participant
MUST complete any participant-specific full-weight alignment and re-difference before privacy,
quantization, encoding, and masking. The coordinator then MUST call the aggregator and use its sum as
the only input to the outer step. The current service does not yet make that call on the commit path.
1. The contract: what the aggregator computes¶
The aggregator takes one masked update per surviving participant and returns the plaintext sum of their
unmasked pseudo-gradients. It never returns, stores, or logs an individual Δ_c.
from dataclasses import dataclass
from typing import Protocol, Mapping
from torch import Tensor
# Fixed-point integer encoding parameters (pinned per round in RoundOpen; see §3).
@dataclass(frozen=True)
class FieldParams:
"""Modular integer field over which masks cancel exactly."""
modulus: int # 2**k, k chosen so C * max|encoded delta| < modulus (no wrap on the sum)
scale: float # fixed-point scale: encoded = round(value * scale); decoded = encoded / scale
dim: int # length of the flat (θ, φ) delta vector
@dataclass(frozen=True)
class MaskedUpdate:
"""Participant c's masked, encoded pseudo-gradient. Carries NO recoverable Δ_c on its own."""
participant_id: str # surviving-set membership; correlation only (redacted from metrics, RFC-0015)
round_index: int # the round t this update is for
masked: Tensor # int64 tensor, shape (dim,), values in [0, modulus): encode(Δ_c) + Σ masks
dataset_root: bytes # the bound Merkle root R_c, in the clear (RFC-0014; INV-COMMIT-BINDING)
class SecureAggregator(Protocol):
"""Backend-agnostic. Pairwise-mask (default) or TEE. lensemble.aggregation.secure_agg."""
def aggregate(
self,
updates: Mapping[str, MaskedUpdate], # surviving participants only
*,
field: FieldParams,
round_index: int,
threshold: int, # t_agg: minimum survivors to reconstruct
recovery: "DropoutRecovery", # secret-shared seeds for dropped/surviving parties (§4)
) -> Tensor: # fp32 plaintext Σ_c Δ_c, shape (dim,)
...
aggregate returns the fp32 plaintext sum Σ_c Δ_c over the surviving set. The result is the exact
input to the outer step (RFC-0003 §2 step 7);
no individual Δ_c is materialized in plaintext anywhere on the aggregator. If fewer than threshold
participants survive, aggregate raises SecureAggregationError and does not return a partial sum.
2. Backend A — pairwise additive masking (default)¶
The default backend is a Bonawitz-style single-server secure-aggregation protocol with pairwise masks, self-masks, and threshold secret sharing for dropout recovery.
Setup (per round, before masking). Each participant c holds a Diffie–Hellman static keypair whose
public key is distributed through the coordinator (the coordinator routes public keys but is not trusted
to read masks — it never holds a private key). For every ordered pair (c, c') with c < c' both
present in the round, the two derive a shared secret s_{c,c'} = KA(sk_c, pk_{c'}) via key agreement,
then a per-round seed seed_{c,c'} = KDF(s_{c,c'} ‖ round_index) domain-separated by the round index.
Key agreement and the channel that carries public keys are part of the control plane
(RFC-0013); this RFC fixes only what the seeds are used for.
Mask derivation. From seed_{c,c'} each pair deterministically expands a pseudo-random integer mask
vector m_{c,c'} ∈ [0, modulus)^dim (a stream cipher / CSPRNG keyed by the seed, same expansion on both
sides). Participant c adds m_{c,c'} for every c' > c and subtracts m_{c,c'} for every
c' < c. Each participant also draws a self-mask b_c ∈ [0, modulus)^dim from a private seed r_c and
adds it.
Masked update. Encode the aligned, privatized pseudo-gradient $\Delta'_c$ to the integer field, add
masks, take the sum modulo modulus:
encode(Δ'_c)[i] = round(Δ'_c[i] * scale) mod modulus
masked_c = ( encode(Δ'_c) + b_c + Σ_{c' > c} m_{c,c'} − Σ_{c' < c} m_{c,c'} ) mod modulus
masked_c is the MaskedUpdate.masked field. Because the field is modular and b_c, m_{c,c'} are
uniform over it, masked_c is computationally indistinguishable from a uniform random vector to anyone
without the seeds; it carries no recoverable Δ_c alone.
Reconstruction (the sum). When every participant in a set S is present, the pairwise masks cancel
because each m_{c,c'} appears once with + (in masked_c) and once with − (in masked_{c'}). The
aggregator must also remove the self-masks Σ_{c∈S} b_c. With the secret-shared seeds (§4) it
reconstructs b_c for every surviving participant and the pairwise seeds for every dropped
participant:
Σ_{c∈S} encode(Δ'_c) = ( Σ_{c∈S} masked_c − Σ_{c∈S} b_c − Σ_{dropped d, c∈S} (±m_{c,d}) ) mod modulus
Σ_{c∈S} Δ'_c = lift_signed( Σ_{c∈S} encode(Δ'_c) ) / scale # fp32, recentred from [0,modulus)
lift_signed maps the modular residue back to a signed integer in (−modulus/2, modulus/2] before
dividing by scale. The modulus is sized (§3) so the true integer sum never wraps, making this lift
exact. The aggregator never learns any individual b_c purpose beyond this cancellation and never holds
two reconstructions that would isolate a single encode(Δ_c).
3. Integer encoding, modulus, and exactness¶
Masks cancel over a finite integer field, not over floating point — float addition is non-associative
and would break both cancellation and INV-AGG-DETERMINISM. The encoding is pinned per round and
recorded in the RunManifest (RFC-0009):
- Fixed-point scale.
encode(x) = round(x * scale) mod modulus.scaleis a power of two so the encode/decode is exact-rounding and reproducible across platforms. - Modulus.
modulus = 2**kwithkchosen so that the maximum possible signed integer sumC * round(C_clip * scale)fits strictly inside(−modulus/2, modulus/2](clipping bounds each‖Δ_c‖ ≤ C_clip,INV-DP-BOUND, RFC-0012). No-wrap on the sum is the precondition that makeslift_signedexact; it is asserted at setup. Storage is int64 per coordinate; the modulus stays below2**62to leave headroom for the additive masks. - Exact cancellation. Modular integer addition is associative and order-independent, so
Σ_c masked_cis identical regardless of the order in which masked updates arrive. The plaintext sum recovered is therefore a deterministic function of the surviving set and the committed updates — it feeds the bitwise-deterministic outer step unchanged (RFC-0003 §7,INV-AGG-DETERMINISM). The per-outer-step determinism self-check (RFC-0003 §7) re-derives the sum in the fixed coordinate order and compares; a mismatch raisesNonDeterministicAggregation(security- and proof-critical, never swallowed).
FieldParams (modulus, scale, dim) is broadcast in RoundOpen
(RFC-0003 §8) so every participant encodes against
identical parameters; a participant encoding against different parameters produces a sum that fails the
no-wrap assertion or the downstream commitment/determinism checks.
4. Dropout robustness (threshold secret sharing)¶
Participants may vanish between submitting a MaskedUpdate and the reconstruction phase
(RFC-0003 §6). The recovery data lets
the aggregator cancel masks for both survivors and dropouts without ever learning an individual
plaintext update.
@dataclass(frozen=True)
class DropoutRecovery:
"""Shamir shares collected during the round, used only at reconstruction."""
threshold: int # t_agg: shares needed to reconstruct any seed
# For each participant, shares of BOTH its self-mask seed r_c and its DH private key sk_c,
# distributed to peers during setup. The aggregator collects shares from survivors only.
self_mask_shares: Mapping[str, list[bytes]] # survivor c -> shares of r_c (reconstruct b_c)
pairwise_shares: Mapping[str, list[bytes]] # dropped d -> shares of sk_d (reconstruct m_{c,d})
The double-masking rule (no isolation under late drop). A participant is either surviving or dropped for a given round, never both, and the aggregator reconstructs exactly one seed per participant:
- For a surviving participant
c, the aggregator reconstructs only the self-mask seedr_c(henceb_c) and neverc's pairwise seeds. This prevents an adversary that observedmasked_cfrom removingc's pairwise masks and isolatingencode(Δ_c). - For a dropped participant
d, the aggregator reconstructs onlyd's DH private keysk_d(hence its pairwise seedsm_{c,d}for survivorsc) and neverd's self-mask. This removes the uncancelled pairwise terms that survivors added againstd.
Both seed kinds are Shamir-secret-shared with threshold t_agg during setup; the aggregator collects
shares from survivors. Reconstruction succeeds iff at least t_agg participants survive; below t_agg
the aggregator cannot recover the masks and raises SecureAggregationError (SECURE_AGG_FAILED) with
fields round, present, threshold, cause (04 §error table). The
state machine (RFC-0013) then retries the round with the surviving
set or aborts; dropped participants reconcile from the latest committed checkpoint next round
(RFC-0010).
t_agg is a deployment-policy value, not yet pinned (Open Questions; shared with
04 §Open Questions and the FaultToleranceExceeded minimum in
RFC-0003 §6). The quorum check for
FaultToleranceExceeded (too few to run a round at all) is distinct from and at least as strict as the
secure-agg threshold for SecureAggregationError (too few to reconstruct the masks).
5. Backend B — TEE-attested aggregator¶
The second supported backend replaces the masking protocol with a hardware enclave. Participants send
plaintext (DP-privatized) Δ_c over a channel terminated inside an attested enclave; the enclave
computes Σ_c Δ_c, returns only the sum, and proves via remote attestation that it ran the pinned,
auditable aggregation code and retains nothing.
@dataclass(frozen=True)
class TEEAttestation:
enclave_measurement: bytes # MRENCLAVE-equivalent: hash of the loaded aggregation code
quote: bytes # signed attestation quote, verified against the vendor root
code_hash: bytes # SHA-256 of the aggregation source pinned in the RunManifest
The participant verifies TEEAttestation (measurement matches the pinned code_hash; quote verifies
against the vendor attestation root) before opening the channel; a failed verification raises
SecureAggregationError (cause="attestation_failed") and the participant refuses to send. The trust
assumption is different from masking: it is hardware-attestation trust rather than the
collusion-bounded honest-but-curious assumption — neither strictly stronger nor weaker
(06 §4 assumptions). The TEE backend is config-selected; the security model
records that it substitutes one residual-trust assumption for the other.
6. Backend selection, data flow, and where it sits in the round¶
The backend is a config choice under the federation/aggregation group
(RFC-0009); both implement SecureAggregator. In the round
(RFC-0003 §2):
participant c: aggregator:
raw local W_c; compute Q_c* on public probe
if drift > τ: transform W_c; Δ'_c = W'_c − W_t (RFC-0002)
else: Δ'_c = W_c − W_t ────────────── INV-ALIGN-BEFORE-RELEASE
clip ‖Δ'_c‖ ≤ C_clip (RFC-0012)
add N(0, σ²C_clip²I) (RFC-0012) ─── DP noise added BEFORE masking
[optional] int8 quantize Δ'_c (RFC-0003 §6)
encode to int field (scale, modulus) (§3)
add self-mask b_c + pairwise masks (§2)
── MaskedUpdate ───────────────────────────────────► Σ_c masked_c (mod modulus)
(Shamir shares distributed at setup) (§4) reconstruct b_c (survivors), m_{c,d} (dropouts)
Σ_c Δ_c (fp32, exact)
determinism self-check (RFC-0003 §7)
── plaintext sum ──► outer Nesterov step
The ordering is normative: participant-specific full-weight alignment → re-difference → clip → noise → optional int8 quantize → integer encode → mask. Noise before masking means the revealed sum already carries the summed Gaussian noise, so DP and secure aggregation compose (RFC-0012, 06 §4). Quantization before encoding means masks operate on the final quantized vector; it is downstream of and does not commute with gauge correction. Once masking reveals only a sum, the aggregator cannot apply a different $Q_c^\star$ to each participant. A TEE/MPC backend that owns the alignment must see raw local weights inside its boundary and execute this same order before emitting only the sum.
7. Invariants enforced¶
These are invariants of the intended integrated protocol. Backend-level tests exercise them within the aggregation boundary; they do not establish that the current coordinator path satisfies individual-update confidentiality.
INV-AGG-DETERMINISM(conventions §7). The revealed sum is a pure, order-independent function of the surviving set and the committed masked updates: masks cancel over an associative integer field (§3), and the subsequent outer step is bitwise-deterministic (RFC-0003 §7). The masking layer adds no nondeterministic reduction. Enforced by the per-outer-step determinism self-check inlensemble.aggregation; a failure raisesNonDeterministicAggregationand the round aborts and recomputes. Never swallowed.INV-ALIGN-BEFORE-RELEASE(conventions §7). TheSecureAggregatoraccepts only already-aligned final releases. Its sum-only interface cannot reconstruct participant-specific raw weights, embeddings, or rotations, so no post-sum Procrustes backstop is permitted.INV-COMMIT-BINDING(conventions §7). Thedataset_roottravels in the clear on eachMaskedUpdate; secure aggregation does not hide it (the binding must remain auditable). A masked update bound to no root or the wrong root is rejected at ingress withCommitmentMismatch(RFC-0014) before it enters the sum.INV-DP-BOUND(conventions §7). The clip bound‖Δ_c‖ ≤ C_clipis the precondition for sizingmodulus(§3); it is enforced upstream inlensemble.privacy.dp(RFC-0012). This RFC depends on it but does not enforce it.INV-RESIDENCY(conventions §7). The aggregator never materializes, logs, or returns an individual plaintextΔ_c; only the sum leaves the aggregation boundary. Redaction (RFC-0015, 05 §5 Redaction) forbids emittingMaskedUpdate.maskedcontent or any reconstructed seed to a log or metric — permitted emissions are the participant set, counts, and the sum's norm.
8. Failure modes¶
| Trigger | Detection | Error | System response |
|---|---|---|---|
Surviving participants fall below t_agg |
aggregator threshold check before reconstruction (§4) | SecureAggregationError (SECURE_AGG_FAILED), fields round, present, threshold, cause="below_threshold" |
retry the round with survivors; dropouts reconcile next round (RFC-0013) |
| Mask reconstruction fails (insufficient/invalid Shamir shares) | share-recombination check (§4) | SecureAggregationError, cause="mask_reconstruction_failed" |
retry; if persistent, abort via state machine |
| Key agreement fails / inconsistent public keys | setup-phase KA verification (§2) | SecureAggregationError, cause="key_agreement_failed" |
retry setup; exclude the offending participant |
| Masks do not cancel (sum wrong) | revealed sum fails the downstream determinism / commitment checks | NonDeterministicAggregation (AGG_NONDETERMINISTIC), fields round, expected_hash, got_hash |
fail-closed; abort outer step and recompute; never swallowed (INV-AGG-DETERMINISM) |
| Integer sum would wrap the modulus | no-wrap assertion at setup / encode (§3) | AggregationError (AGGREGATION_FAILED) |
abort; re-size modulus (config defect, not a runtime path) |
| TEE attestation verification fails | participant verifies quote before sending (§5) | SecureAggregationError, cause="attestation_failed" |
participant refuses to send; round retries or aborts |
A backend tries to return an individual Δ_c |
residency guard on aggregator egress (INV-RESIDENCY) |
ResidencyViolation (RESIDENCY_VIOLATION) |
fail-closed; never caught-and-ignored |
SecureAggregationError is recoverable (retry) — dropout is an expected operating condition, not a
breach. NonDeterministicAggregation and ResidencyViolation are fail-closed and security-critical:
never caught-and-ignored, never downgraded to a warning (04 §error-handling rules).
Alternatives Considered¶
- Pairwise additive masking (chosen default). What it is: the Bonawitz-style single-server protocol
with pairwise masks, self-masks, and threshold secret sharing. Why considered: it gives an
honest-but-curious aggregator a view computationally indistinguishable from learning only the sum, with
practical cost and well-understood dropout recovery, and it is purely additive — so it preserves the
near-linear aggregation the Phase-2 STARK and
INV-AGG-DETERMINISMrely on (RFC-0006 §2). Why chosen: lowest residual-trust assumption that needs no special hardware, and it leaves the outer step bit-identical to the no-security path. - TEE-attested aggregator (chosen alternative backend). What it is: an attested enclave that sees
plaintext
Δ_cand returns only the sum. Why considered: simpler protocol, no per-pair key agreement, and it can also host the Phase-2c attested inner step (RFC-0006 §7). Why offered as a backend, not the only path: it substitutes hardware-attestation trust (vendor root, side-channel exposure) for the collusion-bounded cryptographic assumption — a different trust model some deployments prefer and others reject; making it config-selectable lets the deployment choose. - MPC / homomorphic encryption for the sum. What it is: compute
Σ_c Δ_cunder a general MPC protocol or additively-homomorphic encryption. Why considered: stronger malicious-security properties than single-server masking. Why rejected for Phase 1: order-of-magnitude higher communication and compute for adim ~ 10^8–10^9vector, and the malicious-security gap is exactly what Phase 2 addresses cryptographically through the aggregation STARK over the committed deltas (RFC-0006) rather than at aggregation time. Revisit if a malicious-aggregator guarantee is needed before the STARK lands. - A single trusted aggregator (no masking). What it is: send plaintext
Δ_cto the coordinator and trust it to only compute and reveal the sum. Why considered: trivially simple and the lowest overhead. Why rejected: it defeats the entire point — an honest-but-curious coordinator that sees individualΔ_ccan run gradient inversion against a silo, violating the residency posture (RFC-0003 §5, 06 §4). Rejected by design. - Float-domain masking (mask in fp32, not integer). What it is: add/subtract real-valued masks
directly to the fp32 delta. Why considered: skips the integer encode/decode. Why rejected: fp32
addition is non-associative, so masks would not cancel exactly and the revealed sum would depend on
arrival order — a direct violation of
INV-AGG-DETERMINISM(RFC-0003 §7) and a broken Phase-2 recomputation. The integer field (§3) is required precisely to make cancellation exact.
Drawbacks¶
- Key-agreement and secret-sharing overhead. The pairwise backend needs a setup round of public-key
distribution and
O(C²)per-pair seeds (mask vectors are derived, not stored, so memory isO(dim)per participant, but the share-distribution traffic grows withC). At smallC(Stage B/C) this is negligible; at largeCit motivates grouped/quantized variants (Open Questions). - Dropout-recovery round-trip. Reconstructing masks for late dropouts adds a round-trip after the masked updates arrive; an adaptive adversary that drops participants strategically can force repeated recovery (Open Questions: behavior under adaptive dropout).
- Inherited collusion bound. An aggregator colluding with
C-1participants can isolate the remaining participant's update — the standard single-server secure-aggregation bound. Lensemble inherits it; Phase 1 does not remove it (06 §4 assumptions). DP is residual protection in that worst case only under RFC-0012's participant-secret entropy and accounting contract; the current deterministic replay noise is not (RFC-0012). - TEE backend relies on hardware trust. Enclave attestation depends on a vendor root of trust and is exposed to side-channel and microarchitectural attacks; it is a pragmatic proxy, not a cryptographic guarantee.
- Modulus sizing couples to
C_clip. The no-wrap requirement (§3) ties the integer field width toC * C_clip * scale; a mis-setC_clipor an unexpectedly largeCis caught by the no-wrap assertion, but it is a coupling a deployment must respect when changing either knob.
Migration / Rollout¶
Staged along conventions §12 and the protocol rollout (RFC-0003 §Migration):
- v0.2 / Stage B — simulated, single-process. Direct tests exercise pairwise-mask construction, Shamir recovery, fixed-point summation, threshold failures, and deterministic cancellation. The separate simulated-sum harness has no cryptographic masking. These tests validate the primitives, but the live coordinator still commits from its collected unmasked deltas; Stage-B end-to-end secure aggregation is therefore incomplete.
- v0.3 / Stage C — real multi-party over a network boundary. Real key agreement and share
distribution over the transport (RFC-0013); the masked-update wire
format becomes the on-the-wire
Updatemessage (RFC-0003 §8). The TEE backend, if selected, attests over the real channel. int8 quantization may be enabled once its round-trip error bound is validated.
No contract migration is required between stages: MaskedUpdate, FieldParams, and DropoutRecovery
are stable from v0.2; Stage C swaps the transport and the key-exchange channel, not the protocol
semantics. The on-disk RunManifest records FieldParams and the selected backend so a run is
reproducible (RFC-0009).
Testing Strategy¶
CPU-runnable tests on tiny synthetic fixtures (no large downloads; 07 §8 CI gates):
The current suite validates the aggregation primitives, software TEE boundary, threshold behavior, and
Phase 3 post-commit equivalence report. It does not validate that the committed model was derived
from a secure sum. The missing integration gate must fail if Coordinator.try_round() can access an
individual unmasked delta and must bind the committed outer step to the backend-produced sum.
- Mask cancellation correctness. For random
Δ_c(smallC, smalldim), assert the reconstructedΣ_c Δ_cequals the plaintextΣ_c Δ_cto exact integer equality after decode (the integer field makes this exact, not approximate, modulo the fixed-pointscale). This is the core property (06 §4). - Order independence (
INV-AGG-DETERMINISM). Feed the masked updates toaggregatein several permutations and assert a bit-identical sum each time; assert the downstream outer step's determinism self-check passes (RFC-0003 §Testing). - Dropout recovery, above and below threshold. Simulate participant dropout: with
≥ t_aggsurvivors, the reconstructed sum equals the plaintext sum over survivors; with< t_agg,aggregateraisesSecureAggregationError(present,threshold) and returns no partial sum. Assert the double-masking rule: the aggregator reconstructs the self-mask for survivors and the pairwise seeds for dropouts, never both for the same participant. - No-individual-leak property test. A property test (hypothesis) that no single
MaskedUpdate.maskednor any combination short of the full surviving set lets an adversary recover an individualencode(Δ_c); assert the aggregator never materializes a plaintext individualΔ_c(INV-RESIDENCY). - No-wrap / modulus sizing. Assert the no-wrap assertion fires when
C * round(C_clip * scale)would exceedmodulus/2(raisingAggregationError), and that a correctly sized modulus makeslift_signedexact for adversarial sign patterns. - Alignment-before-release ordering. Assert a participant-specific transform is accepted only before
clip/noise/quantization/masking, and that selecting a coordinator-side backstop with a sum-only backend
fails at configuration preflight (
INV-ALIGN-BEFORE-RELEASE). - DP-then-mask ordering. Assert noise is applied to
Δ_cbefore encoding/masking and that the revealed sum carries the summed noise (compose with RFC-0012 §Testing). - int8 quantization interaction. Quantize/dequantize
Δ_cbefore masking; assert the L2 round-trip error is within the stated bound (RFC-0003 §Testing) and that the dequantized, masked, reconstructed sum still passes the determinism self-check. - TEE backend (simulated). A simulated enclave fixture: a participant rejects a
TEEAttestationwhose measurement ≠ the pinnedcode_hashwithSecureAggregationError(cause="attestation_failed"); a valid attestation yields the correct sum.
Open Questions¶
OPEN QUESTION: The secure-aggregation dropout threshold t_agg (the minimum survivors to reconstruct the
masked sum) is a deployment-policy value, not yet pinned, and is distinct from the FaultToleranceExceeded
minimum (RFC-0003 §6,
04 §Open Questions). Owner @AbdelStark; resolution: Stage C (v0.3) deployment
policy, informed by the Stage-B churn simulation.
OPEN QUESTION: The default backend choice (pairwise masking vs TEE) for the real Stage-C deployment, and whether both are exercised on the two-node demonstration. Owner @AbdelStark; resolution: Stage C (v0.3), coupled to the transport/runtime decision in RFC-0013 §Open Questions.
OPEN QUESTION: Behavior under adaptive (adversarial) dropout, where a party drops strategically to force repeated mask recovery or to influence which seeds the aggregator reconstructs. The double-masking rule (§4) preserves confidentiality per round; the cost and liveness impact under adaptive churn is uncharacterized. Owner @AbdelStark; resolution: Stage C (v0.3) stress simulation.
RISK: At the 1.2B target scale (conventions §12) the dim-length integer mask vectors
and O(C²) per-pair seed material may dominate the per-round budget the masking backend can carry
(08 §4 Communication budget). Resolution plan: measure the masking
overhead in the Stage-C comms accountant; if it dominates, evaluate grouped masking (mask over
participant subgroups), quantized masks, or fall back to the TEE backend (which has no per-pair seed
cost). int8 quantization (§6) already reduces the masked payload by ~4×; the masking overhead itself is
the residual concern.
References¶
- RFC-0003 — Federated Training Protocol — §2 the round that invokes this step, §5 the secure-aggregation requirement and the two protocol-level constraints, §6 int8 quantization and fault tolerance, §7 the determinism contract, §8 the message table.
- RFC-0012 — Differential Privacy Accounting — the Gaussian mechanism and the noise-before-masking ordering this RFC fixes.
- RFC-0013 — Coordinator & Participant Runtime — the transport, the
key-exchange channel, and the state-machine handling of
SecureAggregationError. - RFC-0014 — Provenance Commitments & Merkle Scheme — the
dataset_rootbinding that travels in the clear alongside each masked update. - RFC-0002 — The Latent Gauge & Frame-Anchored Aggregation — the anchored frame that keeps aggregation near-linear, which secure aggregation must not perturb.
- RFC-0006 — Verifiable Contribution — §2 the provable surface (the aggregation-correctness STARK) and §4 the public-recomputation surface, both depending on determinism and linearity; §3 the Phase-1 proof-ready requirements.
- 03 — Data Model (
PseudoGradient,GlobalState) · 04 — Error Model §Secure-aggregation dropout · 05 — Observability §5 Redaction · 06 — Security §4 Secure-aggregation guarantee · 08 — Performance Budget. - External: Bonawitz et al., Practical Secure Aggregation for Privacy-Preserving Machine Learning (pairwise masking, threshold secret sharing for dropout); Shamir secret sharing; DiLoCo / INTELLECT-1 (the int8 all-reduce that composes with masking).