|
1 | 1 | """
|
2 | 2 | Integer FHE with BGV scheme
|
3 | 3 | ========================================
|
4 |
| -//TODO |
5 |
| -""" |
6 |
| - |
7 |
| -# %% |
8 |
| -# 1. Imports |
9 |
| -# --------------------------- |
10 |
| -# We start by importing the library |
11 |
| - |
12 |
| -import numpy as np |
13 |
| -from Pyfhel import Pyfhel |
14 | 4 |
|
15 |
| -print("\n1. Pyfhel Import") |
| 5 | +This demo showcases the use of the BGV scheme for integer FHE operations. |
| 6 | +""" |
16 | 7 |
|
17 | 8 |
|
18 | 9 | # %%
|
19 |
| -# 2. BGV context and key setup |
| 10 | +# 1. BGV context and key setup |
20 | 11 | # ------------------------------------------------------------------------------
|
21 | 12 | # We take a look at the different parameters that can be set for the BGV scheme.
|
| 13 | +import numpy as np |
| 14 | +from Pyfhel import Pyfhel |
22 | 15 | HE = Pyfhel() # Creating empty Pyfhel object
|
23 | 16 |
|
24 | 17 | # HE.contextGen(scheme='bgv', n=2**14, t_bits=20) # Generate context for 'bfv'/'bgv'/'ckks' scheme
|
|
42 | 35 | HE.rotateKeyGen() # Rotate key generation --> Allows rotation/shifting
|
43 | 36 | HE.relinKeyGen() # Relinearization key generation
|
44 | 37 |
|
45 |
| -print("\n2. Pyfhel FHE context generation") |
| 38 | +print("\n1. Pyfhel FHE context generation") |
46 | 39 | print(f"\t{HE}")
|
47 | 40 |
|
48 | 41 |
|
49 | 42 | # %%
|
50 |
| -# 3. BGV Integer Encryption |
| 43 | +# 2. BGV Integer Encryption |
51 | 44 | # ---------------------------
|
52 | 45 | # we will define two integers and encrypt them using `encryptBGV`:
|
53 | 46 | integer1 = np.array([127], dtype=np.int64)
|
|
63 | 56 | print(ctxt2)
|
64 | 57 |
|
65 | 58 | # %%
|
66 |
| -# 4. Operating with encrypted integers in BGV |
| 59 | +# 3. Operating with encrypted integers in BGV |
67 | 60 | # ---------------------------------------------
|
68 | 61 | # Relying on the context defined before, we will now operate
|
69 | 62 | # (addition, substaction, multiplication) the two ciphertexts:
|
70 | 63 | ctxtSum = ctxt1 + ctxt2 # `ctxt1 += ctxt2` for inplace operation
|
71 | 64 | ctxtSub = ctxt1 - ctxt2 # `ctxt1 -= ctxt2` for inplace operation
|
72 | 65 | ctxtMul = ctxt1 * ctxt2 # `ctxt1 *= ctxt2` for inplace operation
|
73 |
| -print("\n4. Operating with encrypted integers") |
| 66 | +print("\n3. Operating with encrypted integers") |
74 | 67 | print(f"Sum: {ctxtSum}")
|
75 | 68 | print(f"Sub: {ctxtSub}")
|
76 | 69 | print(f"Mult:{ctxtMul}")
|
77 | 70 |
|
78 | 71 | # %%
|
79 |
| -# 5. Decrypting BGV integers |
| 72 | +# 4. Decrypting BGV integers |
80 | 73 | # ------------------------------
|
81 | 74 | # Once we're finished with the encrypted operations, we can use
|
82 | 75 | # the Pyfhel instance to decrypt the results using `decryptBGV`:
|
|
85 | 78 | resSub = HE.decrypt(ctxtSub) # `decrypt` function detects the scheme and
|
86 | 79 | # calls the corresponding decryption function.
|
87 | 80 | resMul = HE.decryptBGV(ctxtMul)
|
88 |
| -print("\n5. Decrypting result:") |
| 81 | +print("\n4. Decrypting BGV result:") |
89 | 82 | print(" addition: decrypt(ctxt1 + ctxt2) = ", resSum)
|
90 | 83 | print(" substraction: decrypt(ctxt1 - ctxt2) = ", resSub)
|
91 | 84 | print(" multiplication: decrypt(ctxt1 + ctxt2) = ", resMul)
|
92 | 85 |
|
93 | 86 |
|
94 | 87 | # %%
|
95 |
| -# 6. Integer Array Encoding & Encryption |
| 88 | +# 5. BGV Integer Array Encoding & Encryption |
96 | 89 | # ------------------------------------------------------------------------------
|
97 | 90 | # we will define two 1D integer arrays, encode and encrypt them:
|
98 | 91 | # arr1 = [0, 1, ... n-1] (length n)
|
|
121 | 114 | print("->\tarr2 ", arr2,'\n\t==> ptxt2 ', ptxt2,'\n\t==> ctxt2 ', ctxt2)
|
122 | 115 |
|
123 | 116 | # %%
|
124 |
| -# 7. Securely operating on encrypted ingeger arrays |
| 117 | +# 6. BGV Integer Array Encoding & Encryption |
125 | 118 | # ------------------------------------------------------------------------------
|
126 | 119 | # We try all the operations supported by Pyfhel.
|
127 | 120 | # Note that, to operate, the ciphertexts/plaintexts must be built with the same
|
|
157 | 150 | # `ctxt1 *= ctxt2` for inplace operation
|
158 | 151 |
|
159 | 152 |
|
160 |
| -print("\n7. Secure operations") |
| 153 | +print("\n6. Secure BGV operations") |
161 | 154 | print(" Ciphertext-ciphertext: ")
|
162 | 155 | print("->\tctxt1 + ctxt2 = ccSum: ", ccSum)
|
163 | 156 | print("->\tctxt1 - ctxt2 = ccSub: ", ccSub)
|
|
175 | 168 |
|
176 | 169 |
|
177 | 170 | # %%
|
178 |
| -# 8. BGV Relinearization: What, why, when |
| 171 | +# 7. BGV Relinearization: What, why, when |
179 | 172 | # ------------------------------------------------------------------------------
|
180 | 173 | # Ciphertext-ciphertext multiplications increase the size of the polynoms
|
181 | 174 | # representing the resulting ciphertext. To prevent this growth, the
|
|
188 | 181 | #
|
189 | 182 | # Note that HE.power performs relinearization after every multiplication.
|
190 | 183 |
|
191 |
| -print("\n8. Relinearization-> Right after each multiplication.") |
| 184 | +print("\n7. Relinearization-> Right after each multiplication.") |
192 | 185 | print(f"ccMul before relinearization (size {ccMul.size()}): {ccMul}")
|
193 | 186 | ~ccMul # Equivalent to HE.relinearize(ccMul). Relin always happens in-place.
|
194 | 187 | print(f"ccMul after relinearization (size {ccMul.size()}): {ccMul}")
|
195 | 188 | print(f"cPow after 2 mult&relin rounds: (size {cPow.size()}): {cPow}")
|
196 | 189 |
|
197 | 190 | # %%
|
198 |
| -# 9. Decrypt & Decode results |
| 191 | +# 8. Decrypt & Decode results |
199 | 192 | # ------------------------------------------------------------------------------
|
200 | 193 | # Time to decrypt results! We use HE.decryptBGV for this.
|
201 | 194 | # HE.decrypt() could also be used, in which case the decryption type would be
|
|
214 | 207 | rcpSub = HE.decryptBGV(cpSub)
|
215 | 208 | rcpMul = HE.decryptBGV(cpMul)
|
216 | 209 |
|
217 |
| -print("\n9. Decrypting results") |
| 210 | +print("\n8. Decrypting results") |
218 | 211 | print(" Original ciphertexts: ")
|
219 | 212 | print(" ->\tctxt1 --(decr)--> ", r1)
|
220 | 213 | print(" ->\tctxt2 --(decr)--> ", r2)
|
|
0 commit comments