secretflow.security.aggregation package#

Submodules#

secretflow.security.aggregation.aggregator module#

Classes:

Aggregator()

The abstract aggregator.

class secretflow.security.aggregation.aggregator.Aggregator[source]#

Bases: ABC

The abstract aggregator.

Methods:

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

abstract sum(data: List[DeviceObject], axis=None)[source]#

Sum of array elements over a given axis.

abstract average(data: List[DeviceObject], axis=None, weights=None)[source]#

Compute the weighted average along the specified axis.

secretflow.security.aggregation.plain_aggregator module#

Classes:

PlainAggregator(device)

Plaintext aggregator.

class secretflow.security.aggregation.plain_aggregator.PlainAggregator(device: PYU)[source]#

Bases: Aggregator

Plaintext aggregator.

The computation will be performed in plaintext.

Warning

PlainAggregator is for debugging purpose only. You should not use it in production.

Examples

>>> # Alice and bob are both pyu instances.
>>> aggregator = PlainAggregator(alice)
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.32698634],
  [1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
  dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907046, 0.49698558, 0.7757685 , 0.16349317],
  [0.6441725 , 0.59100014, 0.5884689 , 0.36982694, 0.607682  ]],
  dtype=float32)

Methods:

__init__(device)

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: PYU)[source]#
sum(data: List[DeviceObject], axis=None) PYUObject[source]#

Sum of array elements over a given axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.mean().

Returns

a device object holds the sum.

average(data: List[DeviceObject], axis=None, weights=None) PYUObject[source]#

Compute the weighted average along the specified axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.average().

  • weights – optional. Same as the weights argument of numpy.average().

Returns

a device object holds the weighted average.

secretflow.security.aggregation.secure_aggregator module#

Classes:

SecureAggregator(device, participants[, ...])

The secure aggregation implementation of Masking with One-Time Pads.

class secretflow.security.aggregation.secure_aggregator.SecureAggregator(device: PYU, participants: List[PYU], fxp_bits: int = 18)[source]#

Bases: Aggregator

The secure aggregation implementation of Masking with One-Time Pads.

Masking with One-Time Pads negotiates a secret for every two participants, then uses the secret to hide its input x, and each participant outputs.

\[y_u = x_u + \sum _{u < v}S_{u,v} - \sum_{u>v}S_{u,v}\quad(mod\:R)\]

the secrets are cancelled out after aggregation and then we can get the correct result.

\[\sum y = \sum x\]

For example, the participants Alice, Bob, and Carol each own \(x_1, x_2, x_3\), negotiate the secret \(s_{a,b}, s_{a,c}, s_{b,c}\), and then output:

\[y_1 = x_1 + s_{a,b} + s_{a,c}\]
\[y_2 = x_2 - s_{a,b} + s_{b,c}\]
\[y_3 = x_3 - s_{a,c} - s_{b,c}\]

then it is easy to get

\[y_1 + y_2 + y_3 = x_1 + s_{a,b} + s_{a,c} + x_2 - s_{a,b} + s_{b,c} + x_3 - s_{a,c} - s_{b,c} = x_1 + x_2 + x_3\]

Notes

Masking with One-Time Pads is based on semi-honest assumptions and does not support client dropping. For more information, please refer to Practical Secure Aggregationfor Privacy-Preserving Machine Learning

Warning

The SecureAggregator uses numpy.random.PCG64(). There are many discussions of whether PCG is a CSPRNG (e.g. https://crypto.stackexchange.com/questions/77101/is-the-pcg-prng-a-csprng-or-why-not), we perfer a conservative strategy unless a further security analysis came up. Therefore we recommend users to use a standardized CSPRNG in industrial scenarios.

Examples

>>> # Alice and bob are both pyu instances.
>>> aggregator = SecureAggregator(alice, [alice, bob])
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.3269863 ],
[1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907043, 0.49698558, 0.7757685 , 0.16349316],
[0.6441725 , 0.5910001 , 0.5884689 , 0.3698269 , 0.607682  ]],
dtype=float32)

Methods:

__init__(device, participants[, fxp_bits])

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: PYU, participants: List[PYU], fxp_bits: int = 18)[source]#
sum(data: List[PYUObject], axis=None)[source]#

Sum of array elements over a given axis.

average(data: List[PYUObject], axis=None, weights=None)[source]#

Compute the weighted average along the specified axis.

secretflow.security.aggregation.spu_aggregator module#

Classes:

SPUAggregator(device)

Aggregator based on SPU.

class secretflow.security.aggregation.spu_aggregator.SPUAggregator(device: SPU)[source]#

Bases: Aggregator

Aggregator based on SPU.

The computation will be performed on the given SPU device.

Examples

>>> # spu shall be a SPU device instance.
>>> aggregator = SPUAggregator(spu)
>>> # Alice and bob are both pyu instances.
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.3269863 ],
  [1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
  dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907043, 0.49698558, 0.7757685 , 0.16349316],
  [0.6441725 , 0.5910001 , 0.5884689 , 0.3698269 , 0.607682  ]],
  dtype=float32)

Methods:

__init__(device)

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: SPU)[source]#
sum(data: List[DeviceObject], axis=None) SPUObject[source]#

Sum of array elements over a given axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.mean().

Returns

a device object holds the sum.

average(data: List[DeviceObject], axis=None, weights=None) SPUObject[source]#

Compute the weighted average along the specified axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.average().

  • weights – optional. Same as the weights argument of numpy.average().

Returns

a device object holds the weighted average.

Module contents#

Classes:

Aggregator()

The abstract aggregator.

SecureAggregator(device, participants[, ...])

The secure aggregation implementation of Masking with One-Time Pads.

PlainAggregator(device)

Plaintext aggregator.

SPUAggregator(device)

Aggregator based on SPU.

class secretflow.security.aggregation.Aggregator[source]#

Bases: ABC

The abstract aggregator.

Methods:

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

abstract sum(data: List[DeviceObject], axis=None)[source]#

Sum of array elements over a given axis.

abstract average(data: List[DeviceObject], axis=None, weights=None)[source]#

Compute the weighted average along the specified axis.

class secretflow.security.aggregation.SecureAggregator(device: PYU, participants: List[PYU], fxp_bits: int = 18)[source]#

Bases: Aggregator

The secure aggregation implementation of Masking with One-Time Pads.

Masking with One-Time Pads negotiates a secret for every two participants, then uses the secret to hide its input x, and each participant outputs.

\[y_u = x_u + \sum _{u < v}S_{u,v} - \sum_{u>v}S_{u,v}\quad(mod\:R)\]

the secrets are cancelled out after aggregation and then we can get the correct result.

\[\sum y = \sum x\]

For example, the participants Alice, Bob, and Carol each own \(x_1, x_2, x_3\), negotiate the secret \(s_{a,b}, s_{a,c}, s_{b,c}\), and then output:

\[y_1 = x_1 + s_{a,b} + s_{a,c}\]
\[y_2 = x_2 - s_{a,b} + s_{b,c}\]
\[y_3 = x_3 - s_{a,c} - s_{b,c}\]

then it is easy to get

\[y_1 + y_2 + y_3 = x_1 + s_{a,b} + s_{a,c} + x_2 - s_{a,b} + s_{b,c} + x_3 - s_{a,c} - s_{b,c} = x_1 + x_2 + x_3\]

Notes

Masking with One-Time Pads is based on semi-honest assumptions and does not support client dropping. For more information, please refer to Practical Secure Aggregationfor Privacy-Preserving Machine Learning

Warning

The SecureAggregator uses numpy.random.PCG64(). There are many discussions of whether PCG is a CSPRNG (e.g. https://crypto.stackexchange.com/questions/77101/is-the-pcg-prng-a-csprng-or-why-not), we perfer a conservative strategy unless a further security analysis came up. Therefore we recommend users to use a standardized CSPRNG in industrial scenarios.

Examples

>>> # Alice and bob are both pyu instances.
>>> aggregator = SecureAggregator(alice, [alice, bob])
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.3269863 ],
[1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907043, 0.49698558, 0.7757685 , 0.16349316],
[0.6441725 , 0.5910001 , 0.5884689 , 0.3698269 , 0.607682  ]],
dtype=float32)

Methods:

__init__(device, participants[, fxp_bits])

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: PYU, participants: List[PYU], fxp_bits: int = 18)[source]#
sum(data: List[PYUObject], axis=None)[source]#

Sum of array elements over a given axis.

average(data: List[PYUObject], axis=None, weights=None)[source]#

Compute the weighted average along the specified axis.

class secretflow.security.aggregation.PlainAggregator(device: PYU)[source]#

Bases: Aggregator

Plaintext aggregator.

The computation will be performed in plaintext.

Warning

PlainAggregator is for debugging purpose only. You should not use it in production.

Examples

>>> # Alice and bob are both pyu instances.
>>> aggregator = PlainAggregator(alice)
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.32698634],
  [1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
  dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907046, 0.49698558, 0.7757685 , 0.16349317],
  [0.6441725 , 0.59100014, 0.5884689 , 0.36982694, 0.607682  ]],
  dtype=float32)

Methods:

__init__(device)

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: PYU)[source]#
sum(data: List[DeviceObject], axis=None) PYUObject[source]#

Sum of array elements over a given axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.mean().

Returns

a device object holds the sum.

average(data: List[DeviceObject], axis=None, weights=None) PYUObject[source]#

Compute the weighted average along the specified axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.average().

  • weights – optional. Same as the weights argument of numpy.average().

Returns

a device object holds the weighted average.

class secretflow.security.aggregation.SPUAggregator(device: SPU)[source]#

Bases: Aggregator

Aggregator based on SPU.

The computation will be performed on the given SPU device.

Examples

>>> # spu shall be a SPU device instance.
>>> aggregator = SPUAggregator(spu)
>>> # Alice and bob are both pyu instances.
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> sum_a_b = aggregator.sum([a, b], axis=0)
>>> # Get the result.
>>> sf.reveal(sum_a_b)
array([[0.5954927 , 0.9381409 , 0.99397117, 1.551537  , 0.3269863 ],
  [1.288345  , 1.1820003 , 1.1769378 , 0.7396539 , 1.215364  ]],
  dtype=float32)
>>> average_a_b = aggregator.average([a, b], axis=0)
>>> sf.reveal(average_a_b)
array([[0.29774636, 0.46907043, 0.49698558, 0.7757685 , 0.16349316],
  [0.6441725 , 0.5910001 , 0.5884689 , 0.3698269 , 0.607682  ]],
  dtype=float32)

Methods:

__init__(device)

sum(data[, axis])

Sum of array elements over a given axis.

average(data[, axis, weights])

Compute the weighted average along the specified axis.

__init__(device: SPU)[source]#
sum(data: List[DeviceObject], axis=None) SPUObject[source]#

Sum of array elements over a given axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.mean().

Returns

a device object holds the sum.

average(data: List[DeviceObject], axis=None, weights=None) SPUObject[source]#

Compute the weighted average along the specified axis.

Parameters
  • data – array of device objects.

  • axis – optional. Same as the axis argument of numpy.average().

  • weights – optional. Same as the weights argument of numpy.average().

Returns

a device object holds the weighted average.