New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

phe

Package Overview
Dependencies
Maintainers
4
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

phe - pypi Package Compare versions

Comparing version
1.3.0
to
1.3.1.dev0
+1
benchmarks/__init__.py
from __future__ import absolute_import, division, print_function
__all__ = [
"__title__", "__summary__", "__uri__", "__version__", "__author__",
"__email__", "__license__", "__copyright__",
]
__title__ = "phe"
__summary__ = "Partially Homomorphic Encryption library for Python"
__uri__ = "https://github.com/n1analytics/python-paillier"
# We use semantic versioning - semver.org
__version__ = "1.3.1-dev0"
__author__ = "N1 Analytics developers"
__email__ = "info@n1analytics.com"
__license__ = "GPLv3"
__copyright__ = "Copyright 2013-2018 {0}".format(__author__)
import math
import sys
class EncodedNumber(object):
"""Represents a float or int encoded for Paillier encryption.
For end users, this class is mainly useful for specifying precision
when adding/multiplying an :class:`EncryptedNumber` by a scalar.
If you want to manually encode a number for Paillier encryption,
then use :meth:`encode`, if de-serializing then use
:meth:`__init__`.
.. note::
If working with other Paillier libraries you will have to agree on
a specific :attr:`BASE` and :attr:`LOG2_BASE` - inheriting from this
class and overriding those two attributes will enable this.
Notes:
Paillier encryption is only defined for non-negative integers less
than :attr:`PaillierPublicKey.n`. Since we frequently want to use
signed integers and/or floating point numbers (luxury!), values
should be encoded as a valid integer before encryption.
The operations of addition and multiplication [1]_ must be
preserved under this encoding. Namely:
1. Decode(Encode(a) + Encode(b)) = a + b
2. Decode(Encode(a) * Encode(b)) = a * b
for any real numbers a and b.
Representing signed integers is relatively easy: we exploit the
modular arithmetic properties of the Paillier scheme. We choose to
represent only integers between
+/-:attr:`~PaillierPublicKey.max_int`, where `max_int` is
approximately :attr:`~PaillierPublicKey.n`/3 (larger integers may
be treated as floats). The range of values between `max_int` and
`n` - `max_int` is reserved for detecting overflows. This encoding
scheme supports properties #1 and #2 above.
Representing floating point numbers as integers is a harder task.
Here we use a variant of fixed-precision arithmetic. In fixed
precision, you encode by multiplying every float by a large number
(e.g. 1e6) and rounding the resulting product. You decode by
dividing by that number. However, this encoding scheme does not
satisfy property #2 above: upon every multiplication, you must
divide by the large number. In a Paillier scheme, this is not
possible to do without decrypting. For some tasks, this is
acceptable or can be worked around, but for other tasks this can't
be worked around.
In our scheme, the "large number" is allowed to vary, and we keep
track of it. It is:
:attr:`BASE` ** :attr:`exponent`
One number has many possible encodings; this property can be used
to mitigate the leak of information due to the fact that
:attr:`exponent` is never encrypted.
For more details, see :meth:`encode`.
.. rubric:: Footnotes
.. [1] Technically, since Paillier encryption only supports
multiplication by a scalar, it may be possible to define a
secondary encoding scheme `Encode'` such that property #2 is
relaxed to:
Decode(Encode(a) * Encode'(b)) = a * b
We don't do this.
Args:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.max_int`
varies)
encoding (int): The encoded number to store. Must be positive and
less than :attr:`~PaillierPublicKey.max_int`.
exponent (int): Together with :attr:`BASE`, determines the level
of fixed-precision used in encoding the number.
Attributes:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.max_int`
varies)
encoding (int): The encoded number to store. Must be positive and
less than :attr:`~PaillierPublicKey.max_int`.
exponent (int): Together with :attr:`BASE`, determines the level
of fixed-precision used in encoding the number.
"""
BASE = 16
"""Base to use when exponentiating. Larger `BASE` means
that :attr:`exponent` leaks less information. If you vary this,
you'll have to manually inform anyone decoding your numbers.
"""
LOG2_BASE = math.log(BASE, 2)
FLOAT_MANTISSA_BITS = sys.float_info.mant_dig
def __init__(self, public_key, encoding, exponent):
self.public_key = public_key
self.encoding = encoding
self.exponent = exponent
@classmethod
def encode(cls, public_key, scalar, precision=None, max_exponent=None):
"""Return an encoding of an int or float.
This encoding is carefully chosen so that it supports the same
operations as the Paillier cryptosystem.
If *scalar* is a float, first approximate it as an int, `int_rep`:
scalar = int_rep * (:attr:`BASE` ** :attr:`exponent`),
for some (typically negative) integer exponent, which can be
tuned using *precision* and *max_exponent*. Specifically,
:attr:`exponent` is chosen to be equal to or less than
*max_exponent*, and such that the number *precision* is not
rounded to zero.
Having found an integer representation for the float (or having
been given an int `scalar`), we then represent this integer as
a non-negative integer < :attr:`~PaillierPublicKey.n`.
Paillier homomorphic arithemetic works modulo
:attr:`~PaillierPublicKey.n`. We take the convention that a
number x < n/3 is positive, and that a number x > 2n/3 is
negative. The range n/3 < x < 2n/3 allows for overflow
detection.
Args:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.n`
varies).
scalar: an int or float to be encrypted.
If int, it must satisfy abs(*value*) <
:attr:`~PaillierPublicKey.n`/3.
If float, it must satisfy abs(*value* / *precision*) <<
:attr:`~PaillierPublicKey.n`/3
(i.e. if a float is near the limit then detectable
overflow may still occur)
precision (float): Choose exponent (i.e. fix the precision) so
that this number is distinguishable from zero. If `scalar`
is a float, then this is set so that minimal precision is
lost. Lower precision leads to smaller encodings, which
might yield faster computation.
max_exponent (int): Ensure that the exponent of the returned
`EncryptedNumber` is at most this.
Returns:
EncodedNumber: Encoded form of *scalar*, ready for encryption
against *public_key*.
"""
# Calculate the maximum exponent for desired precision
if precision is None:
if isinstance(scalar, int):
prec_exponent = 0
elif isinstance(scalar, float):
# Encode with *at least* as much precision as the python float
# What's the base-2 exponent on the float?
bin_flt_exponent = math.frexp(scalar)[1]
# What's the base-2 exponent of the least significant bit?
# The least significant bit has value 2 ** bin_lsb_exponent
bin_lsb_exponent = bin_flt_exponent - cls.FLOAT_MANTISSA_BITS
# What's the corresponding base BASE exponent? Round that down.
prec_exponent = math.floor(bin_lsb_exponent / cls.LOG2_BASE)
else:
raise TypeError("Don't know the precision of type %s."
% type(scalar))
else:
prec_exponent = math.floor(math.log(precision, cls.BASE))
# Remember exponents are negative for numbers < 1.
# If we're going to store numbers with a more negative
# exponent than demanded by the precision, then we may
# as well bump up the actual precision.
if max_exponent is None:
exponent = prec_exponent
else:
exponent = min(max_exponent, prec_exponent)
int_rep = int(round(scalar * pow(cls.BASE, -exponent)))
if abs(int_rep) > public_key.max_int:
raise ValueError('Integer needs to be within +/- %d but got %d'
% (public_key.max_int, int_rep))
# Wrap negative numbers by adding n
return cls(public_key, int_rep % public_key.n, exponent)
def decode(self):
"""Decode plaintext and return the result.
Returns:
an int or float: the decoded number. N.B. if the number
returned is an integer, it will not be of type float.
Raises:
OverflowError: if overflow is detected in the decrypted number.
"""
if self.encoding >= self.public_key.n:
# Should be mod n
raise ValueError('Attempted to decode corrupted number')
elif self.encoding <= self.public_key.max_int:
# Positive
mantissa = self.encoding
elif self.encoding >= self.public_key.n - self.public_key.max_int:
# Negative
mantissa = self.encoding - self.public_key.n
else:
raise OverflowError('Overflow detected in decrypted number')
return mantissa * pow(self.BASE, self.exponent)
def decrease_exponent_to(self, new_exp):
"""Return an `EncodedNumber` with same value but lower exponent.
If we multiply the encoded value by :attr:`BASE` and decrement
:attr:`exponent`, then the decoded value does not change. Thus
we can almost arbitrarily ratchet down the exponent of an
:class:`EncodedNumber` - we only run into trouble when the encoded
integer overflows. There may not be a warning if this happens.
This is necessary when adding :class:`EncodedNumber` instances,
and can also be useful to hide information about the precision
of numbers - e.g. a protocol can fix the exponent of all
transmitted :class:`EncodedNumber` to some lower bound(s).
Args:
new_exp (int): the desired exponent.
Returns:
EncodedNumber: Instance with the same value and desired
exponent.
Raises:
ValueError: You tried to increase the exponent, which can't be
done without decryption.
"""
if new_exp > self.exponent:
raise ValueError('New exponent %i should be more negative than'
'old exponent %i' % (new_exp, self.exponent))
factor = pow(self.BASE, self.exponent - new_exp)
new_enc = self.encoding * factor % self.public_key.n
return self.__class__(self.public_key, new_enc, new_exp)
+5
-12
Metadata-Version: 1.1
Name: phe
Version: 1.3.0
Version: 1.3.1.dev0
Summary: Partially Homomorphic Encryption library for Python
Home-page: https://github.com/NICTA/python-paillier
Author: Data61 | CSIRO
Author-email: brian.thorne@nicta.com.au
Home-page: https://github.com/n1analytics/python-paillier
Author: N1 Analytics developers
Author-email: info@n1analytics.com
License: GPLv3

@@ -18,8 +18,6 @@ Download-URL: https://pypi.python.org/pypi/phe/#downloads

+---------------------+
| |coverageM| |
+---------------------+
| |reqM| |
+---------------------+
A library for Partially Homomorphic Encryption in Python.
A Python 3 library for Partially Homomorphic Encryption.

@@ -75,10 +73,5 @@ The homomorphic properties of the paillier crypto system are:

.. |coverageM| image:: https://coveralls.io/repos/n1analytics/python-paillier/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/n1analytics/python-paillier?branch=master
Keywords: cryptography encryption homomorphic
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)

@@ -85,0 +78,0 @@ Classifier: Natural Language :: English

@@ -5,1 +5,4 @@ gmpy2

click
[examples]
sklearn
README.rst
setup.cfg
setup.py
benchmarks/__init__.py
phe/__about__.py
phe/__init__.py
phe/command_line.py
phe/encoding.py
phe/paillier.py

@@ -7,0 +10,0 @@ phe/util.py

@@ -0,1 +1,2 @@

benchmarks
phe

@@ -0,3 +1,4 @@

from phe.__about__ import *
from phe.encoding import EncodedNumber
from phe.paillier import generate_paillier_keypair
from phe.paillier import EncodedNumber
from phe.paillier import EncryptedNumber

@@ -4,0 +5,0 @@ from phe.paillier import PaillierPrivateKey, PaillierPublicKey

#!/usr/bin/env python3
from __future__ import print_function
import datetime

@@ -4,0 +4,0 @@ import json

@@ -22,5 +22,3 @@ #!/usr/bin/env python3

import random
import hashlib
import math
import sys
try:

@@ -31,2 +29,3 @@ from collections.abc import Mapping

from phe import EncodedNumber
from phe.util import invert, powmod, getprimeover, isqrt

@@ -70,2 +69,3 @@

class PaillierPublicKey(object):

@@ -93,5 +93,3 @@ """Contains a public key and associated encryption methods.

def __repr__(self):
nsquare = self.nsquare.to_bytes(1024, 'big')
g = self.g.to_bytes(1024, 'big')
publicKeyHash = hashlib.sha1(nsquare + g).hexdigest()
publicKeyHash = hex(hash(self))[2:]
return "<PaillierPublicKey {}>".format(publicKeyHash[:10])

@@ -222,3 +220,4 @@

raise ValueError('given public key does not match the given p and q.')
if p == q: #check that p and q are different, otherwise we can't compute p^-1 mod q
if p == q:
# check that p and q are different, otherwise we can't compute p^-1 mod q
raise ValueError('p and q have to be different')

@@ -236,4 +235,4 @@ self.public_key = public_key

self.p_inverse = invert(self.p, self.q)
self.hp = self.h_function(self.p, self.psquare);
self.hq = self.h_function(self.q, self.qsquare);
self.hp = self.h_function(self.p, self.psquare)
self.hq = self.h_function(self.q, self.qsquare)

@@ -358,4 +357,3 @@ @staticmethod

return invert(self.l_function(powmod(self.public_key.g, x - 1, xsquare),x), x)
def l_function(self, x, p):

@@ -376,3 +374,3 @@ """Computes the L function as defined in Paillier's paper. That is: L(x,p) = (x-1)/p"""

def __eq__(self, other):
return (self.p == other.p and self.q == other.q)
return self.p == other.p and self.q == other.q

@@ -382,2 +380,3 @@ def __hash__(self):

class PaillierPrivateKeyring(Mapping):

@@ -442,252 +441,2 @@ """Holds several private keys and can decrypt using any of them.

class EncodedNumber(object):
"""Represents a float or int encoded for Paillier encryption.
For end users, this class is mainly useful for specifying precision
when adding/multiplying an :class:`EncryptedNumber` by a scalar.
If you want to manually encode a number for Paillier encryption,
then use :meth:`encode`, if de-serializing then use
:meth:`__init__`.
.. note::
If working with other Paillier libraries you will have to agree on
a specific :attr:`BASE` and :attr:`LOG2_BASE` - inheriting from this
class and overriding those two attributes will enable this.
Notes:
Paillier encryption is only defined for non-negative integers less
than :attr:`PaillierPublicKey.n`. Since we frequently want to use
signed integers and/or floating point numbers (luxury!), values
should be encoded as a valid integer before encryption.
The operations of addition and multiplication [1]_ must be
preserved under this encoding. Namely:
1. Decode(Encode(a) + Encode(b)) = a + b
2. Decode(Encode(a) * Encode(b)) = a * b
for any real numbers a and b.
Representing signed integers is relatively easy: we exploit the
modular arithmetic properties of the Paillier scheme. We choose to
represent only integers between
+/-:attr:`~PaillierPublicKey.max_int`, where `max_int` is
approximately :attr:`~PaillierPublicKey.n`/3 (larger integers may
be treated as floats). The range of values between `max_int` and
`n` - `max_int` is reserved for detecting overflows. This encoding
scheme supports properties #1 and #2 above.
Representing floating point numbers as integers is a harder task.
Here we use a variant of fixed-precision arithmetic. In fixed
precision, you encode by multiplying every float by a large number
(e.g. 1e6) and rounding the resulting product. You decode by
dividing by that number. However, this encoding scheme does not
satisfy property #2 above: upon every multiplication, you must
divide by the large number. In a Paillier scheme, this is not
possible to do without decrypting. For some tasks, this is
acceptable or can be worked around, but for other tasks this can't
be worked around.
In our scheme, the "large number" is allowed to vary, and we keep
track of it. It is:
:attr:`BASE` ** :attr:`exponent`
One number has many possible encodings; this property can be used
to mitigate the leak of information due to the fact that
:attr:`exponent` is never encrypted.
For more details, see :meth:`encode`.
.. rubric:: Footnotes
.. [1] Technically, since Paillier encryption only supports
multiplication by a scalar, it may be possible to define a
secondary encoding scheme `Encode'` such that property #2 is
relaxed to:
Decode(Encode(a) * Encode'(b)) = a * b
We don't do this.
Args:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.max_int`
varies)
encoding (int): The encoded number to store. Must be positive and
less than :attr:`~PaillierPublicKey.max_int`.
exponent (int): Together with :attr:`BASE`, determines the level
of fixed-precision used in encoding the number.
Attributes:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.max_int`
varies)
encoding (int): The encoded number to store. Must be positive and
less than :attr:`~PaillierPublicKey.max_int`.
exponent (int): Together with :attr:`BASE`, determines the level
of fixed-precision used in encoding the number.
"""
BASE = 16
"""Base to use when exponentiating. Larger `BASE` means
that :attr:`exponent` leaks less information. If you vary this,
you'll have to manually inform anyone decoding your numbers.
"""
LOG2_BASE = math.log(BASE, 2)
FLOAT_MANTISSA_BITS = sys.float_info.mant_dig
def __init__(self, public_key, encoding, exponent):
self.public_key = public_key
self.encoding = encoding
self.exponent = exponent
@classmethod
def encode(cls, public_key, scalar, precision=None, max_exponent=None):
"""Return an encoding of an int or float.
This encoding is carefully chosen so that it supports the same
operations as the Paillier cryptosystem.
If *scalar* is a float, first approximate it as an int, `int_rep`:
scalar = int_rep * (:attr:`BASE` ** :attr:`exponent`),
for some (typically negative) integer exponent, which can be
tuned using *precision* and *max_exponent*. Specifically,
:attr:`exponent` is chosen to be equal to or less than
*max_exponent*, and such that the number *precision* is not
rounded to zero.
Having found an integer representation for the float (or having
been given an int `scalar`), we then represent this integer as
a non-negative integer < :attr:`~PaillierPublicKey.n`.
Paillier homomorphic arithemetic works modulo
:attr:`~PaillierPublicKey.n`. We take the convention that a
number x < n/3 is positive, and that a number x > 2n/3 is
negative. The range n/3 < x < 2n/3 allows for overflow
detection.
Args:
public_key (PaillierPublicKey): public key for which to encode
(this is necessary because :attr:`~PaillierPublicKey.n`
varies).
scalar: an int or float to be encrypted.
If int, it must satisfy abs(*value*) <
:attr:`~PaillierPublicKey.n`/3.
If float, it must satisfy abs(*value* / *precision*) <<
:attr:`~PaillierPublicKey.n`/3
(i.e. if a float is near the limit then detectable
overflow may still occur)
precision (float): Choose exponent (i.e. fix the precision) so
that this number is distinguishable from zero. If `scalar`
is a float, then this is set so that minimal precision is
lost. Lower precision leads to smaller encodings, which
might yield faster computation.
max_exponent (int): Ensure that the exponent of the returned
`EncryptedNumber` is at most this.
Returns:
EncodedNumber: Encoded form of *scalar*, ready for encryption
against *public_key*.
"""
# Calculate the maximum exponent for desired precision
if precision is None:
if isinstance(scalar, int):
prec_exponent = 0
elif isinstance(scalar, float):
# Encode with *at least* as much precision as the python float
# What's the base-2 exponent on the float?
bin_flt_exponent = math.frexp(scalar)[1]
# What's the base-2 exponent of the least significant bit?
# The least significant bit has value 2 ** bin_lsb_exponent
bin_lsb_exponent = bin_flt_exponent - cls.FLOAT_MANTISSA_BITS
# What's the corresponding base BASE exponent? Round that down.
prec_exponent = math.floor(bin_lsb_exponent / cls.LOG2_BASE)
else:
raise TypeError("Don't know the precision of type %s."
% type(scalar))
else:
prec_exponent = math.floor(math.log(precision, cls.BASE))
# Remember exponents are negative for numbers < 1.
# If we're going to store numbers with a more negative
# exponent than demanded by the precision, then we may
# as well bump up the actual precision.
if max_exponent is None:
exponent = prec_exponent
else:
exponent = min(max_exponent, prec_exponent)
int_rep = int(round(scalar * pow(cls.BASE, -exponent)))
if abs(int_rep) > public_key.max_int:
raise ValueError('Integer needs to be within +/- %d but got %d'
% (public_key.max_int, int_rep))
# Wrap negative numbers by adding n
return cls(public_key, int_rep % public_key.n, exponent)
def decode(self):
"""Decode plaintext and return the result.
Returns:
an int or float: the decoded number. N.B. if the number
returned is an integer, it will not be of type float.
Raises:
OverflowError: if overflow is detected in the decrypted number.
"""
if self.encoding >= self.public_key.n:
# Should be mod n
raise ValueError('Attempted to decode corrupted number')
elif self.encoding <= self.public_key.max_int:
# Positive
mantissa = self.encoding
elif self.encoding >= self.public_key.n - self.public_key.max_int:
# Negative
mantissa = self.encoding - self.public_key.n
else:
raise OverflowError('Overflow detected in decrypted number')
return mantissa * pow(self.BASE, self.exponent)
def decrease_exponent_to(self, new_exp):
"""Return an `EncodedNumber` with same value but lower exponent.
If we multiply the encoded value by :attr:`BASE` and decrement
:attr:`exponent`, then the decoded value does not change. Thus
we can almost arbitrarily ratchet down the exponent of an
:class:`EncodedNumber` - we only run into trouble when the encoded
integer overflows. There may not be a warning if this happens.
This is necessary when adding :class:`EncodedNumber` instances,
and can also be useful to hide information about the precision
of numbers - e.g. a protocol can fix the exponent of all
transmitted :class:`EncodedNumber` to some lower bound(s).
Args:
new_exp (int): the desired exponent.
Returns:
EncodedNumber: Instance with the same value and desired
exponent.
Raises:
ValueError: You tried to increase the exponent, which can't be
done without decryption.
"""
if new_exp > self.exponent:
raise ValueError('New exponent %i should be more negative than'
'old exponent %i' % (new_exp, self.exponent))
factor = pow(self.BASE, self.exponent - new_exp)
new_enc = self.encoding * factor % self.public_key.n
return self.__class__(self.public_key, new_enc, new_exp)
class EncryptedNumber(object):

@@ -892,3 +641,3 @@ """Represents the Paillier encryption of a float or int.

encoded = EncodedNumber.encode(self.public_key, scalar,
max_exponent=self.exponent)
max_exponent=self.exponent)

@@ -895,0 +644,0 @@ return self._add_encoded(encoded)

#!/usr/bin/env python
# Portions Copyright 2012 Google Inc. All Rights Reserved.
# This file has been modified by NICTA
import phe.encoding
from phe.paillier import PaillierPrivateKey, PaillierPublicKey

@@ -171,3 +172,3 @@

super().setUp()
self.EncodedNumberCls = paillier.EncodedNumber
self.EncodedNumberCls = phe.encoding.EncodedNumber

@@ -395,3 +396,3 @@

class AltEncodedNumber(paillier.EncodedNumber):
class AltEncodedNumber(phe.encoding.EncodedNumber):
BASE = 64

@@ -410,3 +411,3 @@ LOG2_BASE = math.log(BASE, 2)

class AltEncodedNumber(paillier.EncodedNumber):
class AltEncodedNumber(phe.encoding.EncodedNumber):
BASE = 2

@@ -425,3 +426,3 @@ LOG2_BASE = math.log(BASE, 2)

class AltEncodedNumber(paillier.EncodedNumber):
class AltEncodedNumber(phe.encoding.EncodedNumber):
BASE = 13

@@ -489,3 +490,3 @@ LOG2_BASE = math.log(BASE, 2)

ciphertext1 = self.public_key.encrypt(-15)
ciphertext2 = paillier.EncodedNumber(self.other_public_key, 1, ciphertext1.exponent)
ciphertext2 = phe.encoding.EncodedNumber(self.other_public_key, 1, ciphertext1.exponent)
self.assertRaises(ValueError, ciphertext1.__add__, ciphertext2)

@@ -653,3 +654,3 @@

ciphertext1 = self.public_key.encrypt(15)
encoded2 = paillier.EncodedNumber.encode(self.public_key, 1)
encoded2 = phe.encoding.EncodedNumber.encode(self.public_key, 1)
ciphertext3 = ciphertext1 + encoded2

@@ -662,3 +663,3 @@ decryption = self.private_key.decrypt(ciphertext3)

ciphertext1 = self.public_key.encrypt(15)
encoded2 = paillier.EncodedNumber.encode(self.public_key, 1, max_exponent=-50)
encoded2 = phe.encoding.EncodedNumber.encode(self.public_key, 1, max_exponent=-50)
assert encoded2.exponent > -200

@@ -675,3 +676,3 @@ assert ciphertext1.exponent > -200

ciphertext2 = ciphertext1.decrease_exponent_to(-10)
encoded1 = paillier.EncodedNumber.encode(self.public_key, 1)
encoded1 = phe.encoding.EncodedNumber.encode(self.public_key, 1)
encoded2 = encoded1.decrease_exponent_to(-10)

@@ -688,3 +689,3 @@ ciphertext = ciphertext1.decrease_exponent_to(-200)

ciphertext1 = self.public_key.encrypt(-3)
encoded2 = paillier.EncodedNumber.encode(self.public_key, -25)
encoded2 = phe.encoding.EncodedNumber.encode(self.public_key, -25)
ciphertext3 = ciphertext1 * encoded2

@@ -922,3 +923,3 @@ decryption = self.private_key.decrypt(ciphertext3)

self.assertNotEqual(ciphertext2.exponent, ciphertext1.exponent)
exp_of_314 = paillier.EncodedNumber.encode(self.public_key, -31.4).exponent
exp_of_314 = phe.encoding.EncodedNumber.encode(self.public_key, -31.4).exponent
self.assertEqual(ciphertext2.exponent, ciphertext1.exponent +exp_of_314)

@@ -929,4 +930,4 @@

ciphertext1 = self.public_key.encrypt(1.2345678e-12, precision=1e-14)
encoded1 = paillier.EncodedNumber.encode(self.public_key, 1.38734864,
precision=1e-2)
encoded1 = phe.encoding.EncodedNumber.encode(self.public_key, 1.38734864,
precision=1e-2)
ciphertext2 = ciphertext1 * encoded1

@@ -955,3 +956,3 @@ self.assertAlmostEqual(1.71e-12, self.private_key.decrypt(ciphertext2), places=3)

self.assertNotEqual(ciphertext2.exponent, ciphertext1.exponent)
exp_of_314 = paillier.EncodedNumber.encode(self.public_key, -31.4).exponent
exp_of_314 = phe.encoding.EncodedNumber.encode(self.public_key, -31.4).exponent
self.assertEqual(ciphertext2.exponent, ciphertext1.exponent +exp_of_314)

@@ -962,4 +963,4 @@

ciphertext1 = self.public_key.encrypt(1.2345678e-12, precision=1e-14)
encoded1 = paillier.EncodedNumber.encode(self.public_key, -1.38734864,
precision=1e-2)
encoded1 = phe.encoding.EncodedNumber.encode(self.public_key, -1.38734864,
precision=1e-2)
ciphertext2 = ciphertext1 * encoded1

@@ -1001,4 +1002,4 @@ self.assertAlmostEqual(-1.71e-12, self.private_key.decrypt(ciphertext2), places=3)

ciphertext1 = self.public_key.encrypt(0.1, precision=1e-3)
encoded1 = paillier.EncodedNumber.encode(self.public_key, 0.2,
precision=1e-20)
encoded1 = phe.encoding.EncodedNumber.encode(self.public_key, 0.2,
precision=1e-20)
self.assertNotEqual(ciphertext1.exponent, encoded1.exponent)

@@ -1018,7 +1019,7 @@ old_exponent = ciphertext1.exponent

ciphertext1 = self.public_key.encrypt(-0.1)
encoded1 = paillier.EncodedNumber.encode(self.public_key, -31.4)
encoded1 = phe.encoding.EncodedNumber.encode(self.public_key, -31.4)
ciphertext2 = ciphertext1 * encoded1
self.assertEqual(3.14, self.private_key.decrypt(ciphertext2))
self.assertNotEqual(ciphertext2.exponent, ciphertext1.exponent)
exp_of_314 = paillier.EncodedNumber.encode(self.public_key, -31.4).exponent
exp_of_314 = phe.encoding.EncodedNumber.encode(self.public_key, -31.4).exponent
self.assertEqual(ciphertext2.exponent, ciphertext1.exponent +exp_of_314)

@@ -1025,0 +1026,0 @@

Metadata-Version: 1.1
Name: phe
Version: 1.3.0
Version: 1.3.1.dev0
Summary: Partially Homomorphic Encryption library for Python
Home-page: https://github.com/NICTA/python-paillier
Author: Data61 | CSIRO
Author-email: brian.thorne@nicta.com.au
Home-page: https://github.com/n1analytics/python-paillier
Author: N1 Analytics developers
Author-email: info@n1analytics.com
License: GPLv3

@@ -18,8 +18,6 @@ Download-URL: https://pypi.python.org/pypi/phe/#downloads

+---------------------+
| |coverageM| |
+---------------------+
| |reqM| |
+---------------------+
A library for Partially Homomorphic Encryption in Python.
A Python 3 library for Partially Homomorphic Encryption.

@@ -75,10 +73,5 @@ The homomorphic properties of the paillier crypto system are:

.. |coverageM| image:: https://coveralls.io/repos/n1analytics/python-paillier/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/n1analytics/python-paillier?branch=master
Keywords: cryptography encryption homomorphic
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)

@@ -85,0 +78,0 @@ Classifier: Natural Language :: English

@@ -9,8 +9,6 @@ python-paillier |release|

+---------------------+
| |coverageM| |
+---------------------+
| |reqM| |
+---------------------+
A library for Partially Homomorphic Encryption in Python.
A Python 3 library for Partially Homomorphic Encryption.

@@ -66,5 +64,1 @@ The homomorphic properties of the paillier crypto system are:

.. |coverageM| image:: https://coveralls.io/repos/n1analytics/python-paillier/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/n1analytics/python-paillier?branch=master
[metadata]
description-file = README.md
description-file = README.rst

@@ -8,5 +8,4 @@ [bdist_wheel]

[egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
tag_build =
+12
-14

@@ -22,21 +22,18 @@

about = {}
with open(os.path.join(here, "phe", "__about__.py")) as f:
exec(f.read(), about)
def find_version():
# Note the version is also in the docs/conf.py file
# We use semantic versioning - semver.org
return "1.3.0"
setup(
name="phe",
version=find_version(),
description="Partially Homomorphic Encryption library for Python",
name=about['__title__'],
version=about['__version__'],
description=about['__summary__'],
long_description=open(os.path.join(here, "README.rst")).read(),
url="https://github.com/NICTA/python-paillier",
url=about['__uri__'],
download_url="https://pypi.python.org/pypi/phe/#downloads",
author="Data61 | CSIRO",
author_email="brian.thorne@nicta.com.au",
license="GPLv3",
author=about['__author__'],
author_email=about['__email__'],
license=about['__license__'],
classifiers=[
'Development Status :: 4 - Beta',
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',

@@ -62,3 +59,4 @@ 'Natural Language :: English',

extras_require={
'cli': ['click']
'cli': ['click'],
'examples': ['sklearn']
},

@@ -65,0 +63,0 @@ install_requires=['gmpy2'],