123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import time
- import random
- from math import log2
- from openfhe import *
- def main():
- passed = run_demo_pre()
- if not passed: # there could be an error
- return 1
- return 0 # successful return
- def run_demo_pre():
- # Generate parameters.
- print("setting up BFV RNS crypto system")
- start_time = time.time()
- plaintextModulus = 65537 # can encode shorts
- parameters = CCParamsBFVRNS()
- parameters.SetPlaintextModulus(plaintextModulus)
- parameters.SetScalingModSize(60)
- cc = GenCryptoContext(parameters)
- print(f"\nParam generation time: {time.time() - start_time} ms")
- # Turn on features
- cc.Enable(PKE)
- cc.Enable(KEYSWITCH)
- cc.Enable(LEVELEDSHE)
- cc.Enable(PRE)
- print(f"p = {cc.GetPlaintextModulus()}")
- print(f"n = {cc.GetCyclotomicOrder()/2}")
- print(f"log2 q = {log2(cc.GetModulus())}")
- print(f"r = {cc.GetDigitSize()}")
- ringsize = cc.GetRingDimension()
- print(f"Alice can encrypt {ringsize * 2} bytes of data")
- # Perform Key Generation Operation
- print("\nRunning Alice key generation (used for source data)...")
- start_time = time.time()
- keyPair1 = cc.KeyGen()
- print(f"Key generation time: {time.time() - start_time} ms")
- if not keyPair1.good():
- print("Alice Key generation failed!")
- return False
- # Encode source data
- nshort = ringsize
- vShorts = [random.randint(0, 65536) for _ in range(nshort)]
- pt = cc.MakePackedPlaintext(vShorts)
- # Encryption
- start_time = time.time()
- ct1 = cc.Encrypt(keyPair1.publicKey, pt)
- print(f"Encryption time: {time.time() - start_time} ms")
- # Decryption of Ciphertext
- start_time = time.time()
- ptDec1 = cc.Decrypt(keyPair1.secretKey, ct1)
- print(f"Decryption time: {time.time() - start_time} ms")
- ptDec1.SetLength(pt.GetLength())
- # Perform Key Generation Operation
- print("Bob Running key generation ...")
- start_time = time.time()
- keyPair2 = cc.KeyGen()
- print(f"Key generation time: {time.time() - start_time} ms")
- if not keyPair2.good():
- print("Bob Key generation failed!")
- return False
-
- # Perform the proxy re-encryption key generation operation.
- # This generates the keys which are used to perform the key switching.
- print("\nGenerating proxy re-encryption key...")
- start_time = time.time()
- reencryptionKey12 = cc.ReKeyGen(keyPair1.secretKey, keyPair2.publicKey)
- print(f"Key generation time: {time.time() - start_time} ms")
- # Re-Encryption
- start_time = time.time()
- ct2 = cc.ReEncrypt(ct1, reencryptionKey12)
- print(f"Re-Encryption time: {time.time() - start_time} ms")
- # Decryption of Ciphertext
- start_time = time.time()
- ptDec2 = cc.Decrypt(keyPair2.secretKey, ct2)
- print(f"Decryption time: {time.time() - start_time} ms")
- ptDec2.SetLength(pt.GetLength())
- unpacked0 = pt.GetPackedValue()
- unpacked1 = ptDec1.GetPackedValue()
- unpacked2 = ptDec2.GetPackedValue()
- good = True
- # note that OpenFHE assumes that plaintext is in the range of -p/2..p/2
- # to recover 0...q simply add q if the unpacked value is negative
- for j in range(pt.GetLength()):
- if unpacked1[j] < 0:
- unpacked1[j] += plaintextModulus
- if unpacked2[j] < 0:
- unpacked2[j] += plaintextModulus
- # compare all the results for correctness
- for j in range(pt.GetLength()):
- if (unpacked0[j] != unpacked1[j]) or (unpacked0[j] != unpacked2[j]):
- print(f"{j}, {unpacked0[j]}, {unpacked1[j]}, {unpacked2[j]}")
- good = False
- if good:
- print("PRE passes")
- else:
- print("PRE fails")
- print("Execution Completed.")
- return good
- if __name__ == "__main__":
- main()
|