安全聚合协议设计
安全聚合(Secure Aggregation)确保服务器只能获得客户端更新的聚合结果,无法推断任何单个客户端的更新内容。
威胁模型
| 模型 | 攻击者能力 | 防御目标 |
|---|---|---|
| 半诚实 | 遵守协议但试图推断 | 保护个体更新 |
| 恶意 | 可偏离协议 | 保证聚合正确性 |
| 退出 | 客户端随时退出 | 聚合仍可完成 |
基于秘密共享的方案
Shamir 秘密共享
python
import numpy as np
class ShamirSecretSharing:
def __init__(self, threshold, num_parties):
self.threshold = threshold # 恢复阈值
self.num_parties = num_parties
def share(self, secret):
"""将秘密分成 n 份"""
# 生成随机多项式 f(x) = secret + a1*x + a2*x^2 + ...
coefficients = [secret] + [
np.random.randint(0, 2**32) for _ in range(self.threshold - 1)
]
# 计算各份额: f(1), f(2), ..., f(n)
shares = []
for i in range(1, self.num_parties + 1):
share = sum(c * (i ** j) for j, c in enumerate(coefficients))
shares.append(share)
return shares
def reconstruct(self, shares, indices):
"""从 threshold 份恢复秘密(Lagrange 插值)"""
secret = 0
for i, (idx_i, share_i) in enumerate(zip(indices, shares)):
lagrange = 1
for j, idx_j in enumerate(indices):
if i != j:
lagrange *= idx_j / (idx_j - idx_i)
secret += share_i * lagrange
return int(round(secret))基于掩码的方案
Bonawitz 等人提出的实用安全聚合:
python
class MaskedSecureAggregation:
"""基于成对掩码的安全聚合"""
def __init__(self, num_clients, dropout_rate=0.1):
self.num_clients = num_clients
self.dropout_rate = dropout_rate
def pairwise_mask(self, client_id, update, seed_pairs):
"""为客户端添加成对掩码"""
masked_update = update.clone()
for other_id, seed in seed_pairs:
# 确定性伪随机掩码
rng = np.random.RandomState(seed)
mask = torch.from_numpy(rng.randn(*update.shape)).float()
if client_id > other_id:
masked_update += mask
else:
masked_update -= mask
return masked_update聚合时,成对掩码相互抵消,服务器只能看到原始更新的和。
协议对比
| 方案 | 通信轮次 | 通信量 | 容错 | 安全假设 |
|---|---|---|---|---|
| 明文聚合 | 1 | O(d) | 无 | 信任服务器 |
| Shamir SS | 2 | O(nd) | T < n/2 | 诚实多数 |
| 成对掩码 | 3 | O(d+n²) | 任意退出 | 半诚实 |
| 同态加密 | 2 | O(d×log²N) | 无 | 计算安全 |
实际部署选择
- 少量可信参与方:明文聚合即可
- 需要严格隐私:同态加密或秘密共享
- 大规模跨设备:成对掩码(容错性好)
- 恶意环境:需要额外验证机制
通信开销
安全聚合的通信开销通常是明文聚合的 2-10 倍。在大模型场景中,每轮传输的模型更新可达 GB 级别,安全聚合的额外开销不可忽视。