Skip to content

[Bug]: SecAgg+ uses non-cryptographic PRG for mask generation #7522

Description

@AlessandroPerez

Describe the bug

pseudo_rand_gen in framework/py/flwr/common/secure_aggregation/secaggplus_utils.py collapses the input seed to a 32-bit integer and then uses np.random.RandomState to generate the private and pairwise masks.

Why this is a problem:

  • np.random.RandomState is not a cryptographically secure pseudo-random generator
  • XOR-compressing an arbitrary length secret into a 32-bit value throws away almost all entropy before the generator even starts

This weakens the privacy guarantee that the masks are supposed to provide.

A possible fix is to replace np.random.RandomState with a cryptographic PRF/XOF such as SHAKE256 or AES-CTR-DRBG, and use the full seed/key rather than compressing it to 32 bits.

Steps/Code to Reproduce

Mask generation helper used by classical SecAgg+:

from flwr.common.secure_aggregation.secaggplus_utils import pseudo_rand_gen

# This is the same path used inside secaggplus_mod.py for both
# the private mask (rd_seed) and the pairwise masks (ECDH shared_key).
mask = pseudo_rand_gen(b"a" * 32, 1024, [(10,)])

The implementation:

# framework/py/flwr/common/secure_aggregation/secaggplus_utils.py
def pseudo_rand_gen(seed, num_range, dimensions_list):
    assert len(seed) & 0x3 == 0
    seed32 = 0
    for i in range(0, len(seed), 4):
        seed32 ^= int.from_bytes(seed[i : i + 4], "little")
    gen = np.random.RandomState(seed32)

Expected Results

  • Mask generation should use a cryptographically secure pseudo-random function / generator
  • The full entropy of the input secret should be preserved, not compressed to 32 bits
  • An attacker who observes mask values should not be able to reconstruct the seed or predict other mask entries

Actual Results

  • The input seed is XOR-compressed into a 32-bit integer, regardless of its original length
  • np.random.RandomState is used to generate the masks. This generator is not cryptographically secure and is vulnerable to state-recovery attacks given sufficient output
  • The privacy guarantee of the SecAgg+ masks is weakened

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions