예제 #1
0
    def raw_encrypt(self, plaintext, r_value=None):
        """Paillier encryption of a positive integer plaintext < :attr:`n`.

        You probably should be using :meth:`encrypt` instead, because it
        handles positive and negative ints and floats.

        Args:
          plaintext (int): a positive integer < :attr:`n` to be Paillier
            encrypted. Typically this is an encoding of the actual
            number you want to encrypt.
          r_value (int): obfuscator for the ciphertext; by default (i.e.
            r_value is None), a random value is used.

        Returns:
          int: Paillier encryption of plaintext.

        Raises:
          TypeError: if plaintext is not an int.
        """
        if not isinstance(plaintext, int):
            raise TypeError('Expected int type plaintext but got: %s' %
                            type(plaintext))

        if self.n - self.max_int <= plaintext < self.n:
            # Very large plaintext, take a sneaky shortcut using inverses
            neg_plaintext = self.n - plaintext  # = abs(plaintext - nsquare)
            neg_ciphertext = powmod(self.g, neg_plaintext, self.nsquare)
            nude_ciphertext = invert(neg_ciphertext, self.nsquare)
        else:
            nude_ciphertext = powmod(self.g, plaintext, self.nsquare)

        r = r_value or self.get_random_lt_n()
        obfuscator = powmod(r, self.n, self.nsquare)

        return (nude_ciphertext * obfuscator) % self.nsquare
예제 #2
0
def my__mul__(self, other):
    """Multiply by an int, float, or EncodedNumber.
    If `other` is a scalar, it is first encoded to fixed-point precision of `self`"""
    if isinstance(other, paillier.EncryptedNumber):
        raise NotImplementedError('Good luck with that...')
    if isinstance(other, paillier.EncodedNumber):
        encoding = other
    else:
        int_rep = int(other * pow(paillier.EncodedNumber.BASE, -self.exponent))
        if abs(int_rep) > self.public_key.max_int:
            raise ValueError('Integer needs to be within +/- %d but got %d' %
                             (self.public_key.max_int, int_rep))
        # Wrap negative numbers by adding n
        encoding = paillier.EncodedNumber(self.public_key,
                                          int_rep % self.public_key.n,
                                          self.exponent)
    product = self._raw_mul(encoding.encoding)
    exponent = self.exponent + encoding.exponent
    unscaled_result = paillier.EncryptedNumber(self.public_key, product,
                                               exponent)
    # moving the decimal point to end up having the same number of digits to its right
    scaling_multiplier = invert(paillier.EncodedNumber.BASE**(-self.exponent),
                                self.public_key.n)
    scaled_product = unscaled_result._raw_mul(scaling_multiplier)
    return paillier.EncryptedNumber(self.public_key, scaled_product,
                                    self.exponent)
예제 #3
0
    def raw_encrypt(self, plaintext, r_value=None):
        """Paillier encryption of a positive integer plaintext < :attr:`n`.

        You probably should be using :meth:`encrypt` instead, because it
        handles positive and negative ints and floats.

        Args:
          plaintext (int): a positive integer < :attr:`n` to be Paillier
            encrypted. Typically this is an encoding of the actual
            number you want to encrypt.
          r_value (int): obfuscator for the ciphertext; by default (i.e.
            r_value is None), a random value is used.

        Returns:
          int: Paillier encryption of plaintext.

        Raises:
          TypeError: if plaintext is not an int.
        """
        if not isinstance(plaintext, int):
            raise TypeError('Expected int type plaintext but got: %s' %
                            type(plaintext))

        if self.n - self.max_int <= plaintext < self.n:
            # Very large plaintext, take a sneaky shortcut using inverses
            neg_plaintext = self.n - plaintext  # = abs(plaintext - nsquare)
            neg_ciphertext = powmod(self.g, neg_plaintext, self.nsquare)
            nude_ciphertext = invert(neg_ciphertext, self.nsquare)
        else:
            nude_ciphertext = powmod(self.g, plaintext, self.nsquare)

        r = r_value or self.get_random_lt_n()
        obfuscator = powmod(r, self.n, self.nsquare)

        return (nude_ciphertext * obfuscator) % self.nsquare
예제 #4
0
    def _raw_mul(self, plaintext):
        """Returns the integer E(a * plaintext), where E(a) = ciphertext

        Args:
          plaintext (int): number by which to multiply the
            `EncryptedNumber`. *plaintext* is typically an encoding.
            0 <= *plaintext* < :attr:`~PaillierPublicKey.n`

        Returns:
          int: Encryption of the product of `self` and the scalar
            encoded in *plaintext*.

        Raises:
          TypeError: if *plaintext* is not an int.
          ValueError: if *plaintext* is not between 0 and
            :attr:`PaillierPublicKey.n`.
        """
        if not isinstance(plaintext, int):
            raise TypeError('Expected ciphertext to be int, not %s' %
                type(plaintext))

        if plaintext < 0 or plaintext >= self.public_key.n:
            raise ValueError('Scalar out of bounds: %i' % plaintext)

        if self.public_key.n - self.public_key.max_int <= plaintext:
            # Very large plaintext, play a sneaky trick using inverses
            neg_c = invert(self.ciphertext(False), self.public_key.nsquare)
            neg_scalar = self.public_key.n - plaintext
            return powmod(neg_c, neg_scalar, self.public_key.nsquare)
        else:
            return powmod(self.ciphertext(False), plaintext, self.public_key.nsquare)
예제 #5
0
    def raw_decrypt(self, ciphertext):
        """Decrypt raw ciphertext and return raw plaintext.

        Args:
          ciphertext (int): (usually from :meth:`EncryptedNumber.ciphertext()`)
            that is to be Paillier decrypted.

        Returns:
          int: Paillier decryption of ciphertext. This is a positive
          integer < :attr:`public_key.n`.

        Raises:
          TypeError: if ciphertext is not an int.
        """
        if not isinstance(ciphertext, dict):
            raise TypeError('Expected ciphertext to be a dict, not: %s' %
                type(ciphertext))

        #decrypt_to_p = self.l_function(powmod(ciphertext, self.p-1, self.psquare), self.p) * self.hp % self.p
        #decrypt_to_q = self.l_function(powmod(ciphertext, self.q-1, self.qsquare), self.q) * self.hq % self.q
        #return self.crt(decrypt_to_p, decrypt_to_q)

        t1=invert(ciphertext['A'],self.nsquare)
        t2=powmod(t1,self.sk,self.nsquare)
        t3=ciphertext['B']
        t4=t3*t2
        one=powmod(1,1,self.nsquare)
        t5=t4 - one
        t6=t5%self.nsquare
        m = t6 // self.n
        return m
예제 #6
0
    def _raw_mul(self, plaintext):
        """Returns the integer E(a * plaintext), where E(a) = ciphertext

        Args:
          plaintext (int): number by which to multiply the
            `EncryptedNumber`. *plaintext* is typically an encoding.
            0 <= *plaintext* < :attr:`~PaillierPublicKey.n`

        Returns:
          int: Encryption of the product of `self` and the scalar
            encoded in *plaintext*.

        Raises:
          TypeError: if *plaintext* is not an int.
          ValueError: if *plaintext* is not between 0 and
            :attr:`PaillierPublicKey.n`.
        """
        a,b = self, plaintext
        if not isinstance(plaintext, int):
            raise TypeError('Expected ciphertext to be int, not %s' %
                type(plaintext))

        if plaintext < 0 or plaintext >= self.public_key.n:
            raise ValueError('Scalar out of bounds: %i' % plaintext)

        if self.public_key.n - self.public_key.max_int <= plaintext:
            # Very large plaintext, play a sneaky trick using inverses
            neg_c = invert(self.ciphertext, self.public_key.nsquare)
            neg_scalar = self.public_key.n - plaintext
            return powmod(neg_c, neg_scalar, self.public_key.nsquare)
        else:
            return a.exponentiate(plaintext)
    def raw_decrypt(self, ciphertext):

        if not isinstance(ciphertext, int):
            raise TypeError('Expected ciphertext to be an int, not: %s' %
                            type(ciphertext))

        n = self.n
        t = self.t
        SecretKeyShares = self.SecretKeyShares
        theta = self.theta

        nFac = math.factorial(n)

        #c = Ciphertext.ciphertext()
        c = ciphertext
        N = self.public_key.n
        NSquare = N**2
        shares = SecretKeyShares.shares
        degree = SecretKeyShares.degree

        # NB: Here the reconstruction set is implicity defined, but any
        # large enough subset of shares will do.
        reconstruction_shares = {
            key: shares[key]
            for key in list(shares.keys())[:degree + 1]
        }

        lagrange_interpol_enum = {
            i: mult_list([j for j in reconstruction_shares.keys() if i != j])
            for i in reconstruction_shares.keys()
        }
        lagrange_interpol_denom = {
            i: mult_list([(j - i) for j in reconstruction_shares.keys()
                          if i != j])
            for i in reconstruction_shares.keys()
        }
        exponents = [
            (nFac * lagrange_interpol_enum[i] * reconstruction_shares[i]) //
            lagrange_interpol_denom[i] for i in reconstruction_shares.keys()
        ]

        # Notice that the partial decryption is already raised to the power given
        # by the Lagrange interpolation coefficient
        partialDecryptions = [powmod(c, exp, NSquare) for exp in exponents]
        combinedDecryption = mult_list(partialDecryptions) % NSquare

        if (combinedDecryption - 1) % N != 0:
            print("Error, combined decryption minus one not divisible by N")

        message = ((combinedDecryption - 1) // N * invert(theta, N)) % N

        return message
예제 #8
0
 def raw_transform(self,encrypted_number):
     ciphertext = encrypted_number.ciphertext
     if not isinstance(ciphertext, dict):
         raise TypeError('Expected ciphertext to be a dict, not: %s' % type(ciphertext))
     A = ciphertext['A']
     A1 = invert(ciphertext['A'],self.public_key.nsquare)
     t2 = powmod(A1,self.sk,self.public_key.nsquare)
     t3 = ciphertext['B']
     t4=t3*t2
     B=t4%self.public_key.nsquare
     transformed_cipher = {"A":A,"B":B}
     print('transformerssssss',transformed_cipher)
     encrypted_number.ciphertext = transformed_cipher
     return encrypted_number
    def _raw_mul(self, plaintext):
        if not isinstance(plaintext, int):
            raise TypeError('Expected ciphertext to be int, not %s' %
                            type(plaintext))

        if plaintext < 0 or plaintext >= self.public_key.n:
            raise ValueError('Scalar out of bounds: %i' % plaintext)

        if self.public_key.n - self.public_key.max_int <= plaintext:
            # Very large plaintext, play a sneaky trick using inverses
            neg_c = invert(self.ciphertext(False), self.public_key.nsquare)
            neg_scalar = self.public_key.n - plaintext
            return powmod(neg_c, neg_scalar, self.public_key.nsquare)
        else:
            return powmod(self.ciphertext(False), plaintext,
                          self.public_key.nsquare)
예제 #10
0
def secure_bit_decomposition_server(client, public_key, enc_x, bitlength_m):
    l_inv2 = paillier.EncodedNumber.encode(public_key, invert(2, public_key.n))
    T = enc_x + 0
    x_decomp = []

    send(client, bitlength_m)

    for i in range(0, bitlength_m):
        x_decomp.append(secure_lsb_server(client, public_key, T, i))
        Z = T - x_decomp[i]
        T = Z * l_inv2

    if svr_server(client, public_key, enc_x, x_decomp) == 1:
        return list(reversed(x_decomp))
    else:
        return secure_bit_decomposition_server(client, public_key, enc_x,
                                               bitlength_m)
예제 #11
0
 def __init__(self, public_key, p, q):
     if not p*q == public_key.n:
         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
         raise ValueError('p and q have to be different')
     self.public_key = public_key
     if q < p: #ensure that p < q. 
         self.p = q
         self.q = p
     else:
         self.p = p
         self.q = q
     self.psquare = self.p * self.p
     
     self.qsquare = self.q * self.q
     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);
예제 #12
0
    def __init__(self, public_key, p, q):
        if not p*q == public_key.n:
            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
            raise ValueError('p and q have to be different')
        self.public_key = public_key
        if q < p: #ensure that p < q.
            self.p = q
            self.q = p
        else:
            self.p = p
            self.q = q
        self.psquare = self.p * self.p

        self.qsquare = self.q * self.q
        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)
    def raw_encrypt(self, plaintext, r_value=None):

        if not isinstance(plaintext, int):
            raise TypeError('Expected int type plaintext but got: %s' %
                            type(plaintext))

        if self.n - self.max_int <= plaintext < self.n:
            # Very large plaintext, take a sneaky shortcut using inverses
            neg_plaintext = self.n - plaintext  # = abs(plaintext - nsquare)
            neg_ciphertext = (self.n * neg_plaintext + 1) % self.nsquare
            nude_ciphertext = invert(neg_ciphertext, self.nsquare)
        else:
            # we chose g = n + 1, so that we can exploit the fact that
            # (n+1)^plaintext = n*plaintext + 1 mod n^2
            nude_ciphertext = (self.n * plaintext + 1) % self.nsquare

        r = r_value or self.get_random_lt_n()
        obfuscator = powmod(r, self.n, self.nsquare)

        return (nude_ciphertext * obfuscator) % self.nsquare
예제 #14
0
    def raw_encrypt(self, plaintext, r_value=None):
        """Paillier encryption of a positive integer plaintext < :attr:`n`.
            一个正整数的加密
        You probably should be using :meth:`encrypt` instead, because it
        handles positive and negative ints and floats.
        应该使用方法encrypt加密,因为他处理正负的整数和浮点数
        Args:
          plaintext (int): a positive integer < :attr:`n` to be Paillier
            encrypted. Typically this is an encoding of the actual
            number you want to encrypt.
            plaintext(int)为一个小于n的要加密的实际数字编码
          r_value (int): obfuscator for the ciphertext; by default (i.e.
            r_value is None), a random value is used.
        密文模糊处理;默认情况下时(即r_value为None)使用随机值。
        Returns:
          int: Paillier encryption of plaintext.
          plaintext的Paillier加密

        Raises:
          TypeError: if plaintext is not an int.
          异常:plaintext不是整数
        """
        #异常判断
        if not isinstance(plaintext, int):
            raise TypeError('Expected int type plaintext but got: %s' %
                            type(plaintext))
        #加密plaintext
        if self.n - self.max_int <= plaintext < self.n:
            # Very large plaintext, take a sneaky shortcut using inverses
            neg_plaintext = self.n - plaintext  # = abs(plaintext - nsquare)
            neg_ciphertext = (self.n * neg_plaintext + 1) % self.nsquare
            nude_ciphertext = invert(neg_ciphertext, self.nsquare)
        else:
            # we chose g = n + 1, so that we can exploit the fact that
            # (n+1)^plaintext = n*plaintext + 1 mod n^2
            nude_ciphertext = (self.n * plaintext + 1) % self.nsquare

        r = r_value or self.get_random_lt_n()
        obfuscator = powmod(r, self.n, self.nsquare)#使用gmp

        return (nude_ciphertext * obfuscator) % self.nsquare
예제 #15
0
def generate_paillier_keypair(private_keyring=None, n_length=DEFAULT_KEYSIZE):
    """Return a new :class:`PaillierPublicKey` and :class:`PaillierPrivateKey`.

    Add the private key to *private_keyring* if given.

    Args:
      private_keyring (PaillierPrivateKeyring): a
        :class:`PaillierPrivateKeyring` on which to store the private
        key.
      n_length: key size in bits.

    Returns:
      tuple: The generated :class:`PaillierPublicKey` and
      :class:`PaillierPrivateKey`
    """
    p = q = n = None
    n_len = 0
    while n_len != n_length:
        p = getprimeover(n_length // 2)
        q = getprimeover(n_length // 2)
        n = p * q
        n_len = n.bit_length()
    # Simpler Paillier variant with g=n+1 results in lambda equal to phi
    # and mu is phi inverse mod n.
    g = n + 1

    public_key = PaillierPublicKey(g, n)

    phi_n = (p - 1) * (q - 1)
    Lambda = phi_n
    mu = invert(phi_n, n)

    private_key = PaillierPrivateKey(public_key, Lambda, mu)

    if private_keyring is not None:
        private_keyring.add(private_key)

    return public_key, private_key
예제 #16
0
def generate_paillier_keypair(private_keyring=None, n_length=DEFAULT_KEYSIZE):
    """Return a new :class:`PaillierPublicKey` and :class:`PaillierPrivateKey`.

    Add the private key to *private_keyring* if given.

    Args:
      private_keyring (PaillierPrivateKeyring): a
        :class:`PaillierPrivateKeyring` on which to store the private
        key.
      n_length: key size in bits.

    Returns:
      tuple: The generated :class:`PaillierPublicKey` and
      :class:`PaillierPrivateKey`
    """
    p = q = n = None
    n_len = 0
    while n_len != n_length:
        p = getprimeover(n_length // 2)
        q = getprimeover(n_length // 2)
        n = p * q
        n_len = n.bit_length()
    # Simpler Paillier variant with g=n+1 results in lambda equal to phi
    # and mu is phi inverse mod n.
    g = n + 1

    public_key = PaillierPublicKey(g, n)

    phi_n = (p - 1) * (q - 1)
    Lambda = phi_n
    mu = invert(phi_n, n)

    private_key = PaillierPrivateKey(public_key, Lambda, mu)

    if private_keyring is not None:
        private_keyring.add(private_key)

    return public_key, private_key
예제 #17
0
 def h_function(self, x, xsquare):
     """Computes the h-function as defined in Paillier's paper page 12,
     'Decryption using Chinese-remaindering'.
     """
     return invert(self.l_function(powmod(self.public_key.g, x - 1, xsquare),x), x)
예제 #18
0
 def h_function(self, x, xsquare):
     """Computes the h-function as defined in Paillier's paper page 12,
     'Decryption using Chinese-remaindering'.
     """
     return invert(self.l_function(powmod(self.public_key.g, x - 1, xsquare),x), x)
예제 #19
0
 def testInvertNonPrime(self):
     a = 3
     p = 4
     self.assertEqual(a * util.invert(a, p) % p, 1)
예제 #20
0
 def testInvert(self):
     p = 101
     for i in range(1, p):
         iinv = util.invert(i, p)
         self.assertEqual((iinv * i) % p, 1)
예제 #21
0
 def testInvert(self):
     p = 101
     for i in range(1, p):
         iinv = util.invert(i, p)
         self.assertEqual((iinv * i) % p, 1)
예제 #22
0
 def testInvertNonPrime(self):
     a = 3
     p = 4
     self.assertEqual(a * util.invert(a, p) % p, 1)