

!pip install pyfhel pandas psutil

"""**Import Libraries**"""

from Pyfhel import Pyfhel
import pandas as pd
import numpy as np
import time
import sys
import psutil

"""**Load Dataset**"""

# Load dataset
data = pd.read_csv("creditcard.csv")

# Select columns
data_sample = data[['Amount','V1','V2','V3']]

# Start small (increase later)
data_sample = data_sample.head(100)

print("Dataset Loaded:", data_sample.shape)
print(data_sample.head())

"""**Initialize Homomorphic Encryption**"""

HE = Pyfhel()

HE.contextGen(
    scheme='CKKS',
    n=2**14,
    scale=2**30,
    qi_sizes=[60, 30, 30, 60]
)

HE.keyGen()

print("HE context initialized successfully")

"""**Encrypt Data (VECTOR METHOD)**"""

values = data_sample['Amount'].astype(float).values

start_enc = time.time()

ptxt = HE.encodeFrac(values)      # Encode entire array
ctxt = HE.encryptPtxt(ptxt)       # Encrypt once

end_enc = time.time()

print("Encryption Time:", end_enc - start_enc, "seconds")

"""**Encrypted Computation**"""

start_comp = time.time()

# Example operations
result_add = ctxt + ctxt
result_mul = ctxt * ctxt

end_comp = time.time()

print("Computation Time:", end_comp - start_comp, "seconds")

"""**Decrypt Results**"""

decrypted_add = HE.decryptFrac(result_add)
decrypted_mul = HE.decryptFrac(result_mul)

print("Sample Decrypted Addition:", decrypted_add[:5])
print("Sample Decrypted Multiplication:", decrypted_mul[:5])

# Verify correctness
print("Actual Addition:", (values + values)[:5])
print("Actual Multiplication:", (values * values)[:5])

"""**Ciphertext Size Analysis**"""

plaintext_size = values.nbytes
ciphertext_size = len(ctxt.to_bytes())

print("Plaintext Size:", plaintext_size, "bytes")
print("Ciphertext Size:", ciphertext_size, "bytes")

"""**Memory Usage**"""

process = psutil.Process()
memory_usage = process.memory_info().rss / (1024 ** 2)

print("Memory Usage:", memory_usage, "MB")

"""**Scalability Testing**"""

sizes = [100, 1000, 5000]

results = []

for size in sizes:
    sample = data['Amount'].astype(float).values[:size]

    # Encryption
    start = time.time()
    pt = HE.encodeFrac(sample)
    ct = HE.encryptPtxt(pt)
    enc_time = time.time() - start

    # Computation
    start = time.time()
    _ = ct + ct
    comp_time = time.time() - start

    results.append((size, enc_time, comp_time))

print("\nScalability Results:")
for r in results:
    print(f"Size: {r[0]} | Encryption: {r[1]:.4f}s | Computation: {r[2]:.4f}s")

import matplotlib.pyplot as plt

"""**Encryption Time vs Dataset Size**"""

sizes = [r[0] for r in results]
enc_times = [r[1] for r in results]

plt.figure()
plt.plot(sizes, enc_times, marker='o')
plt.xlabel("Dataset Size")
plt.ylabel("Encryption Time (seconds)")
plt.title("Encryption Time vs Dataset Size")
plt.grid()
plt.show()

"""**Computation Time vs Dataset Size**"""

comp_times = [r[2] for r in results]

plt.figure()
plt.plot(sizes, comp_times, marker='o')
plt.xlabel("Dataset Size")
plt.ylabel("Computation Time (seconds)")
plt.title("Computation Time vs Dataset Size")
plt.grid()
plt.show()

"""**Encryption vs Computation Comparison**"""

plt.figure()
plt.plot(sizes, enc_times, marker='o', label='Encryption Time')
plt.plot(sizes, comp_times, marker='o', label='Computation Time')

plt.xlabel("Dataset Size")
plt.ylabel("Time (seconds)")
plt.title("Encryption vs Computation Time")
plt.legend()
plt.grid()
plt.show()