-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutil_fpv.py
223 lines (186 loc) · 6.41 KB
/
util_fpv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# Functions that involve quantization (fixed-point arithmetic) and vector operations
import os
import socket
import sys,struct
import json
from gmpy2 import mpz
import paillier
import numpy as np
try:
import gmpy2
HAVE_GMP = True
except ImportError:
HAVE_GMP = False
# When changing default sizes, remember to change in all other classes: Client, Actuator, util_fpv and keys in paillier and LabHE
DEFAULT_KEYSIZE = 1024
DEFAULT_MSGSIZE = 48
DEFAULT_PRECISION = 24
DEFAULT_SECURITYSIZE = 100
DEFAULT_DGK = 160
NETWORK_DELAY = 0 #0.01 # 10 ms
"""We take the convention that a number x < N/3 is positive, and that a number x > 2N/3 is negative.
The range N/3 < x < 2N/3 allows for overflow detection."""
def encrypt(pubkey, x, coins=None):
if (coins==None):
return pubkey.encrypt(x)
else:
return pubkey.encrypt(x,coins.pop())
def encrypt_vector(pubkey, x, coins=None):
size = np.shape(x)
if len(size) == 1:
if (coins==None):
return [pubkey.encrypt(y) for y in x]
else:
return [pubkey.encrypt(y,coins.pop()) for y in x]
else:
if (coins==None):
return pubkey.encrypt(x)
else:
return pubkey.encrypt(x,coins.pop())
def encrypt_matrix(pubkey, x, coins=None):
size = np.shape(x)
if len(size) == 2:
if (coins==None):
return [[pubkey.encrypt(int(y)) for y in z] for z in x]
else: return [[pubkey.encrypt(int(y),coins.pop()) for y in z] for z in x]
else:
if len(size) == 1:
if (coins==None):
return [pubkey.encrypt(y) for y in x]
else:
return [pubkey.encrypt(y,coins.pop()) for y in x]
else:
if (coins==None):
return pubkey.encrypt(x)
else:
return pubkey.encrypt(x,coins.pop())
def encrypt_multi_dim(pubkey, x, dim, coins = None):
size = len(dim)
if size > 3:
if (coins==None):
return [encrypt_multi_dim(pubkey,y,dim[0:size-1]) for y in x]
else: return [encrypt_multi_dim(pubkey,y,dim[0:size-1],coins) for y in x]
else:
if (coins==None):
return [encrypt_matrix(pubkey,y) for y in x]
else: return [encrypt_matrix(pubkey,y,coins) for y in x]
def encrypt_multi_dim_np(pubkey, x, coins = None):
size = len(x.shape)
if size > 3:
if (coins==None):
return [encrypt_multi_dim_np(pubkey,y) for y in x]
else: return [encrypt_multi_dim_np(pubkey,y,coins) for y in x]
else:
if (coins==None):
return [encrypt_matrix(pubkey,y) for y in x]
else: return [encrypt_matrix(pubkey,y,coins) for y in x]
def decrypt_vector(privkey, x):
return [privkey.decrypt(i) for i in x]
def sum_encrypted_vectors(x, y):
return [x[i] + y[i] for i in range(np.size(x))]
def diff_encrypted_vectors(x, y):
return [x[i] - y[i] for i in range(len(x))]
def mul_sc_encrypted_vectors(x, y): # x is encrypted, y is plaintext
return [y[i]*x[i] for i in range(len(x))]
def dot_sc_encrypted_vectors(x, y): # x is encrypted, y is plaintext
return sum(mul_sc_encrypted_vectors(x,y))
def dot_m_encrypted_vectors(x, A):
return [dot_sc_encrypted_vectors(x,vec) for vec in A]
def Q_s(scalar,prec=DEFAULT_PRECISION):
return int(scalar*(2**prec))/(2**prec)
def Q_vector(vec,prec=DEFAULT_PRECISION):
if np.size(vec)>1:
return [Q_s(x,prec) for x in vec]
else:
return Q_s(vec,prec)
def Q_matrix(mat,prec=DEFAULT_PRECISION):
return [Q_vector(x,prec) for x in mat]
def fp(scalar,prec=DEFAULT_PRECISION):
if isinstance(scalar,np.int64):
scalar = int(scalar)
if prec < 0:
prec = int(prec) # For some reason, without this it throws "conversion error in UI_From_Integer"
return mpz(gmpy2.t_div_2exp(scalar,-prec))
else: return mpz(gmpy2.mul(scalar,2**prec))
def fp_vector(vec,prec=DEFAULT_PRECISION):
if np.size(vec)>1:
return [fp(x,prec) for x in vec]
else:
return fp(vec,prec)
def fp_matrix(mat,prec=DEFAULT_PRECISION):
return [fp_vector(x,prec) for x in mat]
def retrieve_fp(scalar,prec=DEFAULT_PRECISION):
return scalar/(2**prec)
def retrieve_fp_vector(vec,prec=DEFAULT_PRECISION):
return [retrieve_fp(x,prec) for x in vec]
def retrieve_fp_matrix(mat,prec=DEFAULT_PRECISION):
return [retrieve_fp_vector(x,prec) for x in mat]
def off_gen(pubkey, tx, usk):
return pubkey.offline_gen_secret(tx,usk)
def off_gen_vec(pubkey, tx, usk):
size = np.shape(tx)
if len(size) == 1:
return [pubkey.offline_gen_secret(y,usk) for y in tx]
else:
return pubkey.offline_gen_secret(tx,usk)
def off_gen_mat(pubkey, tx, usk):
size = np.shape(tx)
if len(size) == 2:
return [[pubkey.offline_gen_secret(y,usk) for y in z] for z in tx]
else:
if len(size) == 1:
return [pubkey.offline_gen_secret(y,usk) for y in tx]
else:
return pubkey.offline_gen_secret(tx,usk)
# mat = np.array([[pubkey.offline_gen_secret(y,usk) for y in z] for z in tx])
# mat = mat.astype(int)
# return mat
def on_enc(pubkey, x, sx, enc_sx = None):
if enc_sx is None and not isinstance(sx,paillier.EncryptedNumber):
return pubkey.encrypt(x,sx)
else:
return pubkey.encrypt(x,sx,enc_sx)
def on_enc_vec(pubkey, x, sx, enc_sx = None):
size = np.shape(x)
if len(size) == 1:
if enc_sx is None and not isinstance(sx,paillier.EncryptedNumber):
return [pubkey.encrypt(x[i],sx[i]) for i in range(size[0])]
else:
return [pubkey.encrypt(x[i],sx[i],enc_sx[i]) for i in range(size[0])]
else:
return pubkey.encrypt(x,sx,enc_sx)
def on_enc_mat(pubkey, x, sx, enc_sx = None):
size = np.shape(x)
print(type(x[0][0]),type(sx[0][0]),type(enc_sx[0][0]))
if len(size) == 2:
if enc_sx is None and not isinstance(sx,paillier.EncryptedNumber):
return [[pubkey.encrypt(x[i][j],sx[i][j]) for j in range(size[1])] for i in range(size[0])]
else:
return [[pubkey.encrypt(x[i][j],sx[i][j],enc_sx[i][j]) for j in range(size[1])] for i in range(size[0])]
else:
if len(size) == 1:
return on_enc_vec(pubkey, x, sx, enc_sx)
else:
return pubkey.encrypt(x,sx,enc_sx)
def on_dec(privkey, x, sx=None):
if sx is None:
return privkey.decrypt(x)
else:
return privkey.decrypt(x,sx)
def on_dec_vec(privkey, x, sx=None):
if sx is None:
return [privkey.decrypt(x[i]) for i in range(len(x))]
else:
return [privkey.decrypt(x[i],sx[i]) for i in range(len(x))]
def on_dec_mat(privkey, x, sx=None):
if sx is None:
return [[privkey.decrypt(x[i][j]) for j in range(len(x[0]))] for i in range(len(x))]
else:
return [[privkey.decrypt(x[i][j],sx[i][j]) for j in range(len(x[0]))] for i in range(len(x))]
### Vectorize returns everything as np.ndarray
vfp = np.vectorize(fp)
vretrieve_fp = np.vectorize(retrieve_fp)
voff_gen = np.vectorize(off_gen)
vencrypt = np.vectorize(encrypt)
von_enc = np.vectorize(on_enc)
von_dec = np.vectorize(on_dec)