pailliers module

Minimal pure-Python implementation of Paillier’s additively homomorphic cryptosystem.

class secret(bit_length: int)[source]

Bases: Tuple[int, int, int, int]

Wrapper class for a tuple of four integers that represents a secret key.

>>> secret_key = secret(256)
>>> public_key = public(secret_key)
>>> isinstance(secret_key, secret)
True

Any attempt to supply an argument that is of the wrong type or outside the supported range raises an exception.

>>> secret('abc')
Traceback (most recent call last):
  ...
TypeError: bit length must be an integer
>>> secret(0)
Traceback (most recent call last):
  ...
ValueError: bit length must be a positive integer
class public(secret_key: secret)[source]

Bases: Tuple[int, int]

Wrapper class for a pair of integers that represents a public key.

>>> public_key = public(secret(256))
>>> isinstance(public_key, public)
True

Any attempt to supply an argument that is of the wrong type or outside the supported range raises an exception.

>>> public('abc')
Traceback (most recent call last):
  ...
TypeError: secret key required to create public key
class plain[source]

Bases: int

Wrapper class for an integer that represents a plaintext.

>>> isinstance(plain(123), plain)
True
class cipher[source]

Bases: int

Wrapper class for an integer that represents a ciphertext.

>>> secret_key = secret(256)
>>> public_key = public(secret_key)
>>> ciphertext = encrypt(public_key, plain(123))
>>> isinstance(ciphertext, cipher)
True
encrypt(public_key: public, plaintext: Union[plain, int]) cipher[source]

Encrypt the supplied plaintext using the supplied public key.

>>> secret_key = secret(2048)
>>> public_key = public(secret_key)
>>> c = encrypt(public_key, 123)
>>> isinstance(c, cipher)
True

Any attempt to invoke this function using arguments that do not have the expected types raises an exception.

>>> encrypt(secret_key, 123)
Traceback (most recent call last):
  ...
TypeError: can only encrypt using a public key
decrypt(secret_key: secret, ciphertext: cipher) plain[source]

Decrypt the supplied plaintext using the supplied secret key.

>>> secret_key = secret(2048)
>>> public_key = public(secret_key)
>>> c = encrypt(public_key, 123)
>>> decrypt(secret_key, c)
123

Any attempt to invoke this function using arguments that do not have the expected types raises an exception.

>>> decrypt(public_key, c)
Traceback (most recent call last):
  ...
TypeError: can only decrypt using a secret key
>>> decrypt(secret_key, 123)
Traceback (most recent call last):
  ...
TypeError: can only decrypt a ciphertext
add(public_key: public, *ciphertexts: cipher) cipher[source]

Perform addition of encrypted values to produce the encrypted result.

>>> secret_key = secret(2048)
>>> public_key = public(secret_key)
>>> c = encrypt(public_key, 22)
>>> d = encrypt(public_key, 33)
>>> r = add(public_key, c, d)
>>> int(decrypt(secret_key, r))
55

This function supports one or more ciphertexts. If only one ciphertext is supplied, that same ciphertext is returned.

>>> x = encrypt(public_key, 4)
>>> y = encrypt(public_key, 5)
>>> z = encrypt(public_key, 6)
>>> r = add(public_key, x, y, z)
>>> int(decrypt(secret_key, r))
15
>>> r = add(public_key, x)
>>> int(decrypt(secret_key, r))
4

Iterables of ciphertexts can be provided with the help of unpacking via * (thus allowing this function to be used in a manner that resembles the way that the built-in sum function can be used).

>>> r = add(public_key, *(c for c in [x, y, z]))
>>> int(decrypt(secret_key, r))
15

Any attempt to invoke this function using arguments that do not have the expected types raises an exception.

>>> add(secret_key, c, d)
Traceback (most recent call last):
  ...
TypeError: can only perform operation using a public key
>>> add(public_key, c, 123)
Traceback (most recent call last):
  ...
TypeError: can only add ciphertexts
>>> add(public_key)
Traceback (most recent call last):
  ...
ValueError: at least one ciphertext is required
mul(public_key: public, ciphertext: cipher, scalar: int) cipher[source]

Perform multiplication of an encrypted value by a scalar to produce the encrypted result.

>>> secret_key = secret(2048)
>>> public_key = public(secret_key)
>>> c = encrypt(public_key, 22)
>>> r = mul(public_key, c, 3)
>>> int(decrypt(secret_key, r))
66

Any attempt to invoke this function using arguments that do not have the expected types raises an exception.

>>> mul(secret_key, c, 3)
Traceback (most recent call last):
  ...
TypeError: can only perform operation using a public key
>>> mul(public_key, 123, 3)
Traceback (most recent call last):
  ...
TypeError: can only multiply a ciphertext
>>> mul(public_key, c, 'abc')
Traceback (most recent call last):
  ...
TypeError: can only multiply by an integer scalar