108 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import random
 | |
| from math import gcd, lcm
 | |
| from sympy import isprime, randprime
 | |
| 
 | |
| 
 | |
| def generate_prime(bits=512):
 | |
|     # Use sympy's randprime for efficiency
 | |
|     return randprime(2 ** (bits - 1), 2**bits)
 | |
| 
 | |
| 
 | |
| def generate_keypair(bits=512):
 | |
|     p = generate_prime(bits)
 | |
|     q = generate_prime(bits)
 | |
| 
 | |
|     n = p * q
 | |
|     n_squared = n * n
 | |
|     lambda_n = lcm(p - 1, q - 1)
 | |
| 
 | |
|     g = n + 1
 | |
| 
 | |
|     def L(x):
 | |
|         return (x - 1) // n
 | |
| 
 | |
|     # Convert to int to avoid sympy Integer type issues
 | |
|     mu = pow(int(L(pow(g, int(lambda_n), n_squared))), -1, n)
 | |
| 
 | |
|     public_key = (n, g)
 | |
|     private_key = (int(lambda_n), mu)
 | |
| 
 | |
|     return public_key, private_key
 | |
| 
 | |
| 
 | |
| def encrypt(public_key, plaintext):
 | |
|     n, g = public_key
 | |
|     n_squared = n * n
 | |
| 
 | |
|     while True:
 | |
|         r = random.randint(1, n - 1)
 | |
|         if gcd(r, n) == 1:
 | |
|             break
 | |
| 
 | |
|     ciphertext = (pow(g, plaintext, n_squared) * pow(r, n, n_squared)) % n_squared
 | |
| 
 | |
|     return ciphertext
 | |
| 
 | |
| 
 | |
| def decrypt(public_key, private_key, ciphertext):
 | |
|     n, g = public_key
 | |
|     lambda_n, mu = private_key
 | |
|     n_squared = n * n
 | |
| 
 | |
|     def L(x):
 | |
|         return (x - 1) // n
 | |
| 
 | |
|     plaintext = (L(pow(ciphertext, lambda_n, n_squared)) * mu) % n
 | |
| 
 | |
|     return plaintext
 | |
| 
 | |
| 
 | |
| def homomorphic_add(public_key, ciphertext1, ciphertext2):
 | |
|     n, g = public_key
 | |
|     n_squared = n * n
 | |
| 
 | |
|     result = (ciphertext1 * ciphertext2) % n_squared
 | |
| 
 | |
|     return result
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     print("Paillier Encryption Scheme Implementation\n")
 | |
| 
 | |
|     print("Generating keypair...")
 | |
|     public_key, private_key = generate_keypair(bits=512)
 | |
|     print("Keys generated successfully.\n")
 | |
| 
 | |
|     # Get user input for the integers
 | |
|     try:
 | |
|         m1 = int(input("Enter the first integer: "))
 | |
|         m2 = int(input("Enter the second integer: "))
 | |
|     except ValueError:
 | |
|         print("Invalid input. Please enter valid integers.")
 | |
|         return
 | |
| 
 | |
|     print(f"\nOriginal integers: {m1} and {m2}")
 | |
|     print(f"Expected sum: {m1 + m2}\n")
 | |
| 
 | |
|     print("Encrypting integers...")
 | |
|     c1 = encrypt(public_key, m1)
 | |
|     c2 = encrypt(public_key, m2)
 | |
|     print(f"Ciphertext of {m1}: {c1}")
 | |
|     print(f"Ciphertext of {m2}: {c2}\n")
 | |
| 
 | |
|     print("Performing homomorphic addition on encrypted values...")
 | |
|     c_sum = homomorphic_add(public_key, c1, c2)
 | |
|     print(f"Encrypted sum: {c_sum}\n")
 | |
| 
 | |
|     print("Decrypting the result...")
 | |
|     decrypted_sum = decrypt(public_key, private_key, c_sum)
 | |
|     print(f"Decrypted sum: {decrypted_sum}\n")
 | |
| 
 | |
|     if decrypted_sum == m1 + m2:
 | |
|         print("✓ Verification successful! The decrypted sum matches the original sum.")
 | |
|     else:
 | |
|         print("✗ Verification failed! The decrypted sum does not match.")
 | |
| 
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     main()
 |