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
def raw_encrypt(self, plaintext, r_value=None): """DGK encryption of a positive integer plaintext . 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 DGK 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 of 2t bits is used. Returns: int: DGK encryption of plaintext. Raises: TypeError: if plaintext is not an int or mpz. """ if not isinstance(plaintext, int) and not isinstance( plaintext, type(mpz(1))): raise TypeError('Expected int type plaintext but got: %s' % type(plaintext)) nude_ciphertext = powmod(self.g, plaintext, self.n) r = r_value or powmod(self.h, self.get_random_lt_2t(), self.n) # Pass the precomputed obfuscator obfuscator = r return (nude_ciphertext * obfuscator) % self.n
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
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, int): raise TypeError('Expected ciphertext to be an int, 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)
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)
def is_biprime_parametrized(N, pShares, qShares, testValue): """ Test whether N is the product of two primes. If so, this test will succeed with probability 1. If N is not the product of two primes, the test will fail with at least probability 1/2. """ values = [ int(powmod(testValue, x // 4, N)) for x in [ sum(y) for y in zip( list(pShares.values())[1:], list(qShares.values())[1:]) ] ] values = [ int(powmod(testValue, (N - pShares[1] - qShares[1] + 1) // 4, N)) ] + values product = mult_list(values[1:]) if values[0] % N == product % N or values[0] % N == -product % N: # Test succeeds, so N is "probably" the product of two primes. return True # Test fails, so N is definitely not the product of two primes. return False
def raw_decrypt(self, ciphertext): if not isinstance(ciphertext, int): raise TypeError('Expected ciphertext to be an int, 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)
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)
def __init__(self, n,p,q, random_alpha): self.n = n #self.g = n + 1 self.nsquare = n * n self.random_alpha = random_alpha % self.nsquare self.p = p self.q = q self.pp = self.p - 1 // 2 self.qq = self.q -1 // 2 self.g = random.randrange(1048576) self.max_int = n // 3 - 1 one = powmod (1,1,self.nsquare) ppqq=self.pp*self.qq k = powmod(self.g,ppqq,self.n) self.k = k - 1 // self.n self.MK ={"pp":self.pp,"qq":self.qq} self.h = powmod(self.g, self.random_alpha,self.nsquare)
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 = (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 = random.randrange(256) % self.nsquare obfuscator_hr = powmod(self.h, r, self.nsquare) obfuscator_gr = powmod(self.g, r, self.nsquare) A = obfuscator_gr B = (nude_ciphertext * obfuscator_hr) % self.nsquare ciphertext = {"A":A,"B":B} return ciphertext
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, int): raise TypeError('Expected ciphertext to be an int, 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)
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
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_decrypt0(self, ciphertext): """Decrypt raw ciphertext and return raw plaintext. Args: ciphertext (int): (usually from :meth:`EncryptedNumber.ciphertext()`) that is to be DGK decrypted. Returns: int: DGK decryption of ciphertext. 0 if the plaintext is 0 by checking cyphertext^v mod p == 1, 1 otherwise """ c = powmod(ciphertext, self.v, self.p) if c == 1: return 0 else: return 1
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
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
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, int): raise TypeError('Expected ciphertext to be an int, not: %s' % type(ciphertext)) u = powmod(ciphertext, self.Lambda, self.public_key.nsquare) l_of_u = (u - 1) // self.public_key.n return (l_of_u * self.mu) % self.public_key.n
def obfuscate(self): """Disguise ciphertext by multiplying by r ** n with random r. This operation must be performed for every `EncryptedNumber` that is sent to an untrusted party, otherwise eavesdroppers might deduce relationships between this and an antecedent `EncryptedNumber`. For example:: enc = public_key.encrypt(1337) send_to_nsa(enc) # NSA can't decrypt (we hope!) product = enc * 3.14 send_to_nsa(product) # NSA can deduce 3.14 by bruteforce attack product2 = enc * 2.718 product2.obfuscate() send_to_nsa(product) # NSA can't deduce 2.718 by bruteforce attack """ r = self.public_key.get_random_lt_n() r_pow_n = powmod(r, self.public_key.n, self.public_key.nsquare) self.__ciphertext = self.__ciphertext * r_pow_n % self.public_key.nsquare self.__is_obfuscated = True
def obfuscate(self): """Disguise ciphertext by multiplying by r ** n with random r. This operation must be performed for every `EncryptedNumber` that is sent to an untrusted party, otherwise eavesdroppers might deduce relationships between this and an antecedent `EncryptedNumber`. For example:: enc = public_key.encrypt(1337) send_to_nsa(enc) # NSA can't decrypt (we hope!) product = enc * 3.14 send_to_nsa(product) # NSA can deduce 3.14 by bruteforce attack product2 = enc * 2.718 product2.obfuscate() send_to_nsa(product) # NSA can't deduce 2.718 by bruteforce attack """ r = self.public_key.get_random_lt_n() r_pow_n = powmod(r, self.public_key.n, self.public_key.nsquare) self.__ciphertext['A'] = self.__ciphertext['A'] * r_pow_n % self.public_key.nsquare self.__is_obfuscated = True
def obfuscate(self): r = self.public_key.get_random_lt_n() r_pow_n = powmod(r, self.public_key.n, self.public_key.nsquare) self.__ciphertext = self.__ciphertext * r_pow_n % self.public_key.nsquare self.__is_obfuscated = True
def testPowMod(self): self.assertEqual(util.powmod(5, 3, 3), 2) self.assertEqual(util.powmod(2, 10, 1000), 24)
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)
def exponentiate(self,m): ciphertext=self.ciphertext text ={} text['A'] = powmod(ciphertext['A'],m, self.public_key.nsquare) text['B'] = powmod(ciphertext['B'],m,self.public_key.nsquare) return text
def handle_client(conn): #Sending message to connected client #conn.send('Welcome to the server. Type something and hit enter\n'.encode('ASCII')) #send only takes string #infinite loop so that function do not terminate and thread do not end. while True: #Receiving blinded message from client data = conn.recv(1024) print(sys.getsizeof(data), data) if not data: break #determine if ZKP was sent or blind signature print("Data: ", data) try: print("Data decoded: ", data.decode('ascii')) if data.decode('ascii') == "ZKP START": print("here...") #start ZKP for i in range(1, 5): successful = False #used to control if the multiplicative inverse of x^e does not exist, then repeat the round while not successful: #wait for u c = conn.recv(2049) print("C data: ", c) c = int(c.decode('ascii')) print("Received c: ", c) u = conn.recv(2048) u = int(u.decode('ascii')) print("Received u: ", u) A = random.randint(3, 20) e = random.randint(0, A) print("e: ", e) conn.send(bytes(str(e), 'ascii')) wn = conn.recv(2048) wn = wn.decode('ascii') if wn != "restart": wn = int(wn) print("wn: ", wn) v = conn.recv(2048) v = int(v.decode('ascii')) print("v: ", v) gv = powmod(public_key.g, v, public_key.nsquare) ce = powmod(c, e, public_key.nsquare) check = (gv * ce * wn) % public_key.nsquare print("N2: ", public_key.nsquare) print("Check: ", check) print("u: ", u) if check == u: conn.send(bytes("PASS ROUND", 'ascii')) successful = True elif check == "Invalid": conn.send(bytes("REPEAT ROUND", 'ascii')) else: conn.send(bytes("FAILED ROUND", 'ascii')) successful = True else: print( "Retrying with new s and e... no inverse to w." ) except UnicodeDecodeError: print("there...") #print(type(data),data.decode('ascii'),data) #calculate signature msg_blinded_signature = RSA_private_key.sign(data, 0) print(msg_blinded_signature[0]) print(type(msg_blinded_signature[0])) #send the signature, second element is always None conn.send(bytes(str(msg_blinded_signature[0]), 'ascii')) except ValueError: pass