The number 128 is not a must but rather a target. In the [specs] 1 it is actually defined as the TARGET_COMMITTEE_SIZE
.
They write:
For the safety of committees, TARGET_COMMITTEE_SIZE exceeds the recommended minimum committee size of 111; with sufficient active validators (at least SLOTS_PER_EPOCH * TARGET_COMMITTEE_SIZE), the shuffling algorithm ensures committee sizes of at least TARGET_COMMITTEE_SIZE.
Next, to determine the actual size of the committee, they use this target when possible, as shown in the function determining the number of committees:
def get_committee_count_per_slot(state: BeaconState, epoch: Epoch) -> uint64:
"""
Return the number of committees in each slot for the given ``epoch``.
"""
return max(uint64(1), min(
MAX_COMMITTEES_PER_SLOT,
uint64(len(get_active_validator_indices(state, epoch))) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE,
))
As you can see, the return function makes sure that there is at least uint64(1)
committee per slot, and if it is possible to do more, they must at most be MAX_COMMITTEES_PER_SLOT
which is 64 or the number of committees such that all of them have at least TARGET_COMMITTEE_SIZE
member.
After that validators are pseudo-randomly affected to committees of at least TARGET_COMMITTEE_SIZE
: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_committee