|
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