secretflow.security package#

Subpackages#

Submodules#

secretflow.security.diffie_hellman module#

Classes:

DiffieHellman([group])

Diffie-Hellman implementation.

class secretflow.security.diffie_hellman.DiffieHellman(group=15)[source]#

Bases: object

Diffie-Hellman implementation.

Examples

>>> df1 = DiffieHellman()
>>> df2 = DiffieHellman()
>>> pub_key1, pri_key1 = df1.generate_key_pair()
>>> pub_key2, pri_key2 = df2.generate_key_pair()
>>> secret1 = df1.generate_secret(pri_key1, pub_key2)
>>> secret2 = df2.generate_secret(pri_key2, pub_key1)
>>> secret1 == secret2
True

Methods:

__init__([group])

param group

optional; MODP Groups, the default is 15 which has

generate_secret(private_key, peer_public_key)

Generate secret.

generate_key_pair([num_key_bits])

Generate key pair.

__init__(group=15)[source]#
Parameters

group – optional; MODP Groups, the default is 15 which has a 130 bits or 260 exponent size of security strength.

generate_secret(private_key, peer_public_key) str[source]#

Generate secret.

The DH secret will be hashed with sha256 before returned.

Parameters
  • private_key – the private key.

  • peer_public_key – the public key of peer.

Returns

A secret in hex string.

generate_key_pair(num_key_bits=256) Tuple[source]#

Generate key pair.

Parameters

num_key_bits – optional, bits of key.

Returns

A tuple of (public_key, private_key).

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.

Comparator()

The abstract comparator.

DeviceComparator(device)

Comparator based on a device (PYU or SPU).

PlainComparator(device)

Plaintext compartator.

SPUComparator(device)

Compartator based on SPU.

class secretflow.security.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.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.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.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.

class secretflow.security.Comparator[source]#

Bases: ABC

The abstract comparator.

Methods:

min(data[, axis, reveal])

The minimum of array over a given axis.

max(data[, axis, reveal])

The maximum of array over a given axis.

abstract min(data: List[DeviceObject], axis=None, reveal=False)[source]#

The minimum of array over a given axis.

abstract max(data: List[DeviceObject], axis=None, reveal=False)[source]#

The maximum of array over a given axis.

class secretflow.security.DeviceComparator(device: Union[PYU, SPU])[source]#

Bases: Comparator

Comparator based on a device (PYU or SPU).

device#

a PYU or SPU. The device where the computation hosts.

Type

Union[secretflow.device.device.pyu.PYU, secretflow.device.device.spu.SPU]

Attributes:

device

Methods:

min(data[, axis])

The minimum of array over a given axis.

max(data[, axis])

The maximum of array over a given axis.

__init__(device)

device: Union[PYU, SPU]#
min(data: List[DeviceObject], axis=None)[source]#

The minimum of array over a given axis.

Parameters
  • data – array of device objects.

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

Returns

a device object holds the minimum.

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

The maximum of array over a given axis.

Parameters
  • data – array of device objects.

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

Returns

a device object holds the maximum.

__init__(device: Union[PYU, SPU]) None#
class secretflow.security.PlainComparator(device: Union[PYU, SPU])[source]#

Bases: DeviceComparator

Plaintext compartator.

The computation will be performed in plaintext.

Warning

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

Examples

>>> import numpy as np
# Alice and bob are both pyu instances.
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> comparator = PlainComparator(alice)
>>> min_a_b = comparator.min([a, b], axis=0)
>>> sf.reveal(min_a_b)
array([[0.47092903, 0.77865475, 0.05917433, 0.07155096, 0.16089967],
    [0.56598   , 0.51047045, 0.35771865, 0.23004009, 0.23400909]],
    dtype=float32)
    >>> max_a_b = comparator.max([a, b], axis=0)
>>> sf.reveal(max_a_b)
array([[0.5939065 , 0.8463326 , 0.14722177, 0.9977698 , 0.6186677 ],
    [0.65607053, 0.611439  , 0.957074  , 0.6548823 , 0.445968  ]],
    dtype=float32)

Attributes:

device: Union[PYU, SPU]#
class secretflow.security.SPUComparator(device: Union[PYU, SPU])[source]#

Bases: DeviceComparator

Compartator based on SPU.

The computation will be performed on the given SPU device.

Examples

>>> import numpy as np
# Alice and bob are both pyu instances.
>>> a = alice(lambda : np.random.rand(2, 5))()
>>> b = bob(lambda : np.random.rand(2, 5))()
>>> comparator = SPUComparator(alice)
>>> min_a_b = comparator.min([a, b], axis=0)
>>> sf.reveal(min_a_b)
array([[0.47092903, 0.77865475, 0.05917433, 0.07155096, 0.16089967],
    [0.56598   , 0.51047045, 0.35771865, 0.23004009, 0.23400909]],
    dtype=float32)
>>> max_a_b = comparator.max([a, b], axis=0)
>>> sf.reveal(max_a_b)
array([[0.5939065 , 0.8463326 , 0.14722177, 0.9977698 , 0.6186677 ],
    [0.65607053, 0.611439  , 0.957074  , 0.6548823 , 0.445968  ]],
    dtype=float32)

Attributes:

device: Union[PYU, SPU]#