Ejemplo n.º 1
0
    def setPoints(self, folder, n, m, p, d, T, A, B, C, W, V, F):
        self.n = n
        self.m = m
        self.p = p
        self.T = T
        self.d = d
        x0 = np.loadtxt("Data/" + folder + "/x0.txt",
                        delimiter=',',
                        dtype=float)
        xr = np.loadtxt("Data/" + folder + "/xr.txt",
                        delimiter=',',
                        dtype=float)
        ur = np.loadtxt("Data/" + folder + "/ur.txt",
                        delimiter=',',
                        dtype=float)

        x0 = x0.reshape(n)
        xr = xr.reshape(n)
        ur = ur.reshape(m)

        self.x = x0
        self.x_series = np.zeros((n, T + 1))
        self.x_series[:, 0] = x0
        self.xr = xr
        self.ur = ur
        self.xf = util_fpv.vfp(x0)
        self.xrf = util_fpv.vfp(xr)
        self.urf = util_fpv.vfp(ur)

        self.A = A
        self.B = B
        self.C = C
        self.W = W
        self.V = V
        self.F = F
Ejemplo n.º 2
0
    def computeProducts(self):
        lf = DEFAULT_PRECISION
        # Compute LCA encrypted
        prod_LCA = Mult3Matrix(self.enc_L, self.enc_C, self.enc_A,
                               self.enc_bLC, self.enc_bLA, self.enc_bCA)
        self.enc_LCA = prod_LCA

        # Compute Gamma2 = (I-LC)BK = BK - LCBK = Gamma3*K
        enc_Gamma2 = np.dot(self.enc_Gamma3, self.enc_K)

        rGamma2 = [[
            gmpy2.mpz_urandomb(gmpy2.random_state(), self.l + lf + self.sigma)
            for i in range(self.n)
        ] for j in range(self.n)]

        self.rGamma2 = util_fpv.vfp(rGamma2, -lf)

        # Compute Gamma = (I-LC)(A+BK) = A + BK - LCA - LCBK, they have different precisions
        enc_Gamma = (
            np.dot(self.enc_A, 2**(2 * lf) * np.eye(self.n, dtype=object)) -
            prod_LCA +
            np.dot(enc_Gamma2, 2**lf * np.eye(self.n, dtype=object)))

        rGamma = [[
            gmpy2.mpz_urandomb(gmpy2.random_state(),
                               self.l + 2 * lf + self.sigma)
            for i in range(self.n)
        ] for j in range(self.n)]

        self.rGamma = util_fpv.vfp(rGamma, -2 * lf)

        return enc_Gamma + rGamma, enc_Gamma2 + rGamma2
Ejemplo n.º 3
0
    def refresh_Gamma1_2(self, blinded_Gamma, blinded_Gamma2):
        lf = DEFAULT_PRECISION
        old_bGamma = (
            np.dot(self.bGamma3K, 2**lf * np.eye(self.n, dtype=object)) -
            self.bLCA)
        Gammar = util_fpv.von_dec(self.privkey, blinded_Gamma) + old_bGamma
        new_Gamma = util_fpv.von_enc(self.pubkey,
                                     util_fpv.vfp(Gammar,
                                                  -2 * lf), self.bGamma)

        Gammar2 = util_fpv.von_dec(self.privkey, blinded_Gamma2, self.bGamma3K)
        new_Gamma2 = util_fpv.von_enc(self.pubkey, util_fpv.vfp(Gammar2, -lf),
                                      self.bGamma2)

        return new_Gamma, new_Gamma2
Ejemplo n.º 4
0
 def refresh_xk(self, blinded_xk, k):
     bxkr = self.bxkr[:, k - 1]
     # xkr = util_fpv.von_dec(self.privkey,blinded_xk)+bxkr
     # print('act x%d: '%(k+1), util_fpv.vfp(xkr,-2*DEFAULT_PRECISION)'')
     ## if Gref is not a full LabHE encryption, but rather [[Gref - bGref]], then perform
     # bxk = bxkr + self.bGref
     xkr = util_fpv.von_dec(self.privkey, blinded_xk, bxkr)
     return util_fpv.von_enc(self.pubkey,
                             util_fpv.vfp(xkr, -DEFAULT_PRECISION),
                             self.bx[:, k])
Ejemplo n.º 5
0
    def refresh_Gamma3(self, blinded_Gamma3):
        lf = DEFAULT_PRECISION

        old_bGamma3 = self.bLCB * (-1)
        Gammar3 = util_fpv.von_dec(self.privkey, blinded_Gamma3) + old_bGamma3
        new_Gamma3 = util_fpv.von_enc(self.pubkey,
                                      util_fpv.vfp(Gammar3, -2 * lf),
                                      self.bGamma3)

        return new_Gamma3
Ejemplo n.º 6
0
 def generateRandomness(self):
     n = self.n
     m = self.m
     T = self.T
     state = gmpy2.random_state()
     rk = [
         gmpy2.mpz_urandomb(state, self.l + self.sigma)
         for i in range(n * T)
     ]
     self.rk = rk
     self.rkf = util_fpv.vfp(rk, -DEFAULT_PRECISION)
Ejemplo n.º 7
0
 def getMeasurement(self, k):
     z = np.add(
         np.dot(self.C, self.x),
         np.random.multivariate_normal([0] * self.p, self.V, tol=1e-6))
     # z = np.dot(self.C,self.x)	# no noise
     # z = np.array(z, dtype=object)
     self.z = z
     # print("Measurement z%d: "%(k+1),["%.5f"% i for i in z])
     enc_bz = [item[k] for item in self.enc_bz]
     enc_z = util_fpv.von_enc(self.pubkey, util_fpv.vfp(z), self.bz[:, k],
                              enc_bz)
     return enc_z
Ejemplo n.º 8
0
    def encryptMatrices(self, flag):
        pubkey = self.pubkey
        self.enc_A = util_fpv.von_enc(pubkey, self.Af, self.bA, self.enc_bA)
        # print('A: ',util_fpv.retrieve_fp_matrix(util_fpv.on_dec_mat(privkey,enc_A,act.bA)))
        self.enc_C = util_fpv.von_enc(pubkey, self.Cf, self.bC, self.enc_bC)
        # print('C: ',util_fpv.retrieve_fp_matrix(util_fpv.on_dec_mat(privkey,enc_C,act.bC)))
        self.enc_L = util_fpv.von_enc(pubkey, self.Lf, self.bL, self.enc_bL)
        # print('L: ',util_fpv.retrieve_fp_matrix(util_fpv.on_dec_mat(privkey,enc_L,act.bL)))
        self.enc_B = util_fpv.von_enc(pubkey, self.Bf, self.bB, self.enc_bB)
        # print('B: ',util_fpv.retrieve_fp_matrix(util_fpv.on_dec_mat(privkey,enc_B,act.bB)))
        self.enc_K = util_fpv.von_enc(pubkey, self.Kf, self.bK, self.enc_bK)

        if flag == 0:
            self.enc_Gamma = util_fpv.von_enc(pubkey, util_fpv.vfp(self.Gamma),
                                              self.bGamma, self.enc_bGamma)
            self.enc_Gamma2 = util_fpv.von_enc(pubkey,
                                               util_fpv.vfp(self.Gamma2),
                                               self.bGamma2, self.enc_bGamma2)
            self.enc_Gamma3 = util_fpv.von_enc(pubkey,
                                               util_fpv.vfp(self.Gamma3),
                                               self.bGamma3, self.enc_bGamma3)
Ejemplo n.º 9
0
 def closedLoop(self, u, k):
     # print("Last input: ", ["%.5f"% i for i in u])
     # with np.errstate(invalid='ignore'):
     # np.warnings.filterwarnings('ignore')
     x = np.add(
         np.dot(self.A, self.x), np.dot(self.B, u),
         np.dot(
             self.F,
             np.random.multivariate_normal([0] * self.d, self.W, tol=1e-6)))
     # x = np.dot(self.A,self.x) + np.dot(self.B,u) # no noise
     self.x = x
     self.x_series[:, k] = x
     self.xf = util_fpv.vfp(x)
Ejemplo n.º 10
0
    def computeGamma3(self):
        lf = DEFAULT_PRECISION
        # Compute LCB encrypted
        prod_LCB = Mult3Matrix(self.enc_L, self.enc_C, self.enc_B,
                               self.enc_bLC, self.enc_bLB, self.enc_bCB)
        self.enc_LCB = prod_LCB

        # Compute Gamma3 = (I-LC)B = B - LCB, they have different precisions
        enc_Gamma3 = np.dot(
            self.enc_B, 2**(2 * lf) * np.eye(self.m, dtype=object)) - prod_LCB

        rGamma3 = [[
            gmpy2.mpz_urandomb(gmpy2.random_state(),
                               self.l + 2 * lf + self.sigma)
            for i in range(self.m)
        ] for j in range(self.n)]

        self.rGamma3 = util_fpv.vfp(rGamma3, -2 * lf)

        return enc_Gamma3 + rGamma3
Ejemplo n.º 11
0
def main():
	""" Run instances of encrypted LQG with Labeled Homomorphic Encryption."""

	flag = 0 # The Setup computes gives the gain matrices Gamma to the cloud if flag = 0, otherwise, the cloud and actuator compute their encryption
	verbose = 0 # Print values of variables if verbose = 1, does nothing otherwise

	# folder = 'building_1_room' 
	# folder = 'Random_instance_5_1'
	folder = 'building_2_rooms'
	# folder = 'Random_instance_25_5'
	# folder = 'Random_instance_50_10'
	# folder = 'Random_instance_75_15'
	# folder = 'Random_instance_100_20'
	# folder = 'Random_instance_125_25'

	lf = DEFAULT_PRECISION
	T = 100
	setup = Client.Client()
	usk_setup = setup.usk
	setup.Plant(T,folder)
	n = setup.n; m = setup.m; p = setup.p; d = setup.d
	A = setup.Af; B = setup.Bf; C = setup.Cf
	K = setup.Kf; L = setup.Lf
	W = setup.Wf; V = setup.Vf; F = setup.F

	client = Client.Client()
	usk_client = client.usk
	client.setPoints(folder,n,m,p,d,T,setup.A,setup.B,setup.C,setup.W,setup.V,setup.F)
	x0 = client.xf;	
	xr = client.xr; ur = client.ur
	xrf = client.xrf; urf = client.urf
	plaintext_x_series = np.zeros((n,T))

	act = Actuator.Actuator(usk_setup,usk_client)
	privkey = act.privkey
	msk = privkey.msk; upk = privkey.upk
	pubkey = act.pubkey

	client.getPubkey(pubkey)
	setup.getPubkey(pubkey)

	start = time.time()
	setup.genLabelsSetup(flag)
	time_off_setup = time.time() - start
	print('Offline time for setup: ', "%.5f" % (time_off_setup), ' sec')
	start = time.time()

	client.genLabels()
	time_off_clients = time.time() - start
	print('Offline time for clients: ', "%.5f" % (time_off_clients), ' sec')
	start = time.time()

	cloud = Cloud.Cloud(act.pubkey,n,m,p,T)
	cloud.generateRandomness()
	time_off_cloud = time.time() - start
	print('Offline time for cloud: ', "%.5f" % (time_off_cloud), ' sec')
	start = time.time()

	act.genLabels(n,m,p,T,flag)
	
	if flag == 1:
		act.genProgramSecrets()
	time_off_act = time.time() - start
	print('Offline time for actuator: ', "%.5f" % (time_off_act), ' sec')
	start = time.time()

	setup.encryptMatrices(flag)
	time_in_setup = time.time() - start
	print('Online time to compute constants for setup: ', "%.5f" % (time_in_setup), ' sec')

	start = time.time()
	client.encryptSetPoints()
	time_in_clients = time.time() - start
	print('Online time to compute constants for clients: ', "%.5f" % (time_in_clients), ' sec')

	if flag == 1:
		start = time.time()
		cloud.getCoeff(setup.enc_A,setup.enc_B,setup.enc_C,setup.enc_L,setup.enc_K,client.enc_xr,client.enc_ur)
		cloud.getProgramSecrets(act.enc_bLC,act.enc_bLA,act.enc_bCA,act.enc_bLB,act.enc_bCB)

		blinded_enc_Gamma3 = cloud.computeGamma3()
		# The actuator needs to refresh Gamma3
		start_act = time.time()			
		blinded_enc_Gamma3 = act.refresh_Gamma3(blinded_enc_Gamma3)
		time_in_act = time.time() - start_act
		cloud.getGamma3(blinded_enc_Gamma3)
		blinded_enc_Gamma, blinded_enc_Gamma2 = cloud.computeProducts()
		# The actuator needs to refresh Gamma, Gamma2, Gamma3
		start_act = time.time()	
		blinded_enc_Gamma, blinded_enc_Gamma2 = act.refresh_Gamma1_2(blinded_enc_Gamma, blinded_enc_Gamma2)
		time_in_act = time.time() - start_act + time_in_act
		print('Online time to compute constants for actuator: ', "%.5f" % (time_in_act), ' sec')
		cloud.getGamma1_2(blinded_enc_Gamma, blinded_enc_Gamma2)
		cloud.computeConstants()
		time_in_cloud = time.time() - start - time_in_act
		print('Online time to compute constants for cloud: ', "%.5f" % (time_in_cloud), ' sec')

	if flag == 0:
		Gamma = setup.Gamma; Gamma2 = setup.Gamma2; Gamma3 = setup.Gamma3
		enc_Gamma = setup.enc_Gamma; enc_Gamma2 = setup.enc_Gamma2; enc_Gamma3 = setup.enc_Gamma3
	else:
		Gamma = np.dot(np.eye(n, dtype = object) - np.dot(setup.L,setup.C),setup.A + np.dot(setup.B,setup.K))
		Gamma2 = np.dot(np.eye(n, dtype = object) - np.dot(setup.L,setup.C),np.dot(setup.B,setup.K))
		Gamma3 = np.dot(np.eye(n, dtype = object) - np.dot(setup.L,setup.C),setup.B)
		enc_Gamma = util_fpv.von_enc(pubkey,util_fpv.vfp(Gamma),act.bGamma,act.enc_bGamma)
		enc_Gamma2 = util_fpv.von_enc(pubkey,util_fpv.vfp(Gamma2),act.bGamma2,act.enc_bGamma2)
		enc_Gamma3 = util_fpv.von_enc(pubkey,util_fpv.vfp(Gamma3),act.bGamma3,act.enc_bGamma3)

	Gref = np.dot(Gamma3, client.ur) - np.dot(Gamma2, client.xr)
	Gref_2 = 2**lf*Gref
	uref = ur - np.dot(setup.K, client.xr)
	uref_2 = np.dot(uref,2**lf*np.eye(m,dtype = object))

	cloud.enc_Gamma = enc_Gamma
	cloud.enc_Gamma2 = enc_Gamma2
	cloud.enc_Gamma3 = enc_Gamma3

	if flag == 0:
		time_in_act = 0
		start = time.time()
		cloud.getCoeff(setup.enc_A,setup.enc_B,setup.enc_C,setup.enc_L,setup.enc_K,client.enc_xr,client.enc_ur)
		cloud.computeConstants()
		time_in_cloud = time.time() - start
		print('Online time to compute constants for cloud: ', "%.5f" % (time_in_cloud), ' sec')

	if verbose == 1:
		hat_x = np.zeros((n,T+1))
		enc_x0 = util_fpv.von_enc(pubkey,x0,act.bx[:,0],util_fpv.vencrypt(pubkey.Pai_key,act.bx[:,0]))
		print('x0: ',util_fpv.vretrieve_fp(util_fpv.von_dec(privkey,enc_x0,
				util_fpv.vencrypt(pubkey.Pai_key,act.bx[:,0]))))

	start = time.time()

	k = 0
	cloud.xk = client.enc_x0
	enc_u0 = cloud.computeInput()
	u0 = act.getInput(enc_u0,k)
	if verbose == 1:
		plaintext_xk = client.x
		plaintext_x_series[:,k] = plaintext_xk
		hat_x[:,k] = util_fpv.vretrieve_fp(util_fpv.von_dec(privkey,cloud.xk,act.bx[:,k]))
		print('decrypted x%d: '%k, ["%.5f"% i for i in hat_x[:,k]])
		print('decrypted u%d: '%k, ["%.5f"% i for i in u0])
		print('u0: ', ["%.5f"% i for i in np.dot(setup.K,client.x) + uref])

	# Get next state and measurement
	client.closedLoop(u0,k+1)
	enc_zk = client.getMeasurement(k) # The measurement time is k+1 but the labels are generated for k
	if verbose == 1:
		plaintext_zk = client.z
		print('z1: ', ["%.5f"% i for i in plaintext_zk])
		print('decrypted z%d: '%(k+1), ["%.5f"% i for i in util_fpv.vretrieve_fp(util_fpv.von_dec(privkey,enc_zk))])

		print('Online time for iteration %d: '%k, "%.5f" % (time.time() - start), ' sec')

	time_act = np.zeros((T-1,1))
	time_cloud = np.zeros((T-1,1))
	time_client = np.zeros((T-1,1))

	# Start the control loop
	for k in range(1,T):
		start_it = time.time()
		blinded_xk = cloud.computeEstimate(cloud.xk,enc_zk)
		start_act = time.time()	
		enc_xk2 = act.refresh_xk(blinded_xk,k)
		end_act = time.time()-start_act
		cloud.getEstimate(enc_xk2)		# get xk

		if verbose == 1:
			hat_x[:,k] = util_fpv.vretrieve_fp(util_fpv.von_dec(privkey,cloud.xk,act.bx[:,k]))
			print('decrypted x%d: '%k, ["%.5f"% i for i in hat_x[:,k]])
			plaintext_xk = np.dot(Gamma,plaintext_xk)+np.dot(setup.L,plaintext_zk)+Gref
			plaintext_x_series[:,k] = plaintext_xk
			print('x%d: '%k, ["%.5f"% i for i in plaintext_xk])

		enc_uk = cloud.computeInput()

		start_act = time.time()
		uk = act.getInput(enc_uk,k)			# get uk
		time_act[k-1] = end_act + time.time() - start_act
		if verbose == 1:
			print('decrypted u%d: '%k, uk)
			print('u%d: '%k, ["%.5f"% i for i in np.dot(setup.K,plaintext_xk)+uref])

		client.closedLoop(uk,k+1)

		start_cl = time.time()
		enc_zk = client.getMeasurement(k)	# get zk+1
		time_client[k-1] = time.time() - start_cl
		if verbose == 1:
			plaintext_zk = client.z
			plaintext_zk = util_fpv.vretrieve_fp(util_fpv.von_dec(privkey,enc_zk,
					util_fpv.vencrypt(pubkey.Pai_key,act.bz[:,k])))
			print('z%d: '%(k+1), ["%.5f"% i for i in plaintext_zk])

		time_cloud[k-1] = time.time() - start_it - time_act[k-1] - time_client[k-1]

	print('Total online time for %d iterations: '%T, "%.5f" % (time.time() - start), ' sec')

	print('Mean online time for client for one iteration: ', " %.5f" % np.mean(time_client), ' sec')
	print('Mean online time for actuator for one iteration: ', " %.5f" % np.mean(time_act), ' sec')
	print('Mean online time for cloud for one iteration: ', " %.5f" % np.mean(time_cloud), ' sec')

	# print("%.5f, %.5f MB" % (memory_usage_resource(),memory_usage_psutil()))

	with open(os.path.abspath('results_'+str(DEFAULT_KEYSIZE)+'_'+str(DEFAULT_PRECISION)+'.txt'),'a+') as f: 
		f.write("%d, %d, %d, flag %d\n " % (n,m,T,flag));
		f.write("Offline time:\n setup: %.5f, client: %.5f, cloud: %.5f, actuator %.5f\n" % (time_off_setup, time_off_clients, time_off_cloud, time_off_act))
		f.write("Initialization time:\n setup: %.5f, client: %.5f, cloud: %.5f, actuator %.5f\n" % (time_in_setup, time_in_clients, time_in_cloud, time_in_act))
		f.write("Online time 1 iter:\n client: %.5f, cloud: %.5f, actuator %.5f\n" % (np.mean(time_client), np.mean(time_act), np.mean(time_cloud)))


	if folder == 'building_2_rooms' and verbose == 1:
		# evenly sampled time at 440s intervals
		Ts = 420
		t = Ts*np.arange(0., T)

		fig, ax = plt.subplots(figsize=(16,8))

		for i in range(int(n/2)):
			ax.plot(t, hat_x[i,:-1], 'C'+str(i), linewidth=2)
			ax.plot(t, hat_x[int(n/2)+i,:-1], 'C'+str(int(n/2)+i)+'--', linewidth=2)
			# ax.plot(t, plaintext_x_series[i,:],'C'+str(i)+'--',linewidth=2)

		ax.set(xlabel='Time (s)', ylabel='State x',
		       title='Evolution of the estimates')
		ax.grid()
		plt.legend(('$\hat x_1$', '$\hat x_6$', '$\hat x_2$', '$\hat x_7$', '$\hat x_3$', '$\hat x_8$',
			'$\hat x_4$', '$\hat x_9$', '$\hat x_5$', '$\hat x_{10}$'),
		           loc='lower right', shadow=True)
		fig.savefig("Figures/estimates.png")
		fig.show()

		fig2, ax = plt.subplots(figsize=(16,8))

		t = Ts*np.arange(0., T)
		for i in range(int(n/2)):
			ax.plot(t, client.x_series[i,:-1], 'C'+str(i), linewidth=2)
			ax.plot(t, client.x_series[int(n/2)+i,:-1], 'C'+str(int(n/2)+i)+'--', linewidth=2)
			# ax.plot(t, plaintext_x_series[i,:],'C'+str(i)+'--',linewidth=2)

		ax.set(xlabel='Time (s)', ylabel='State x',
		       title='Evolution of the true states')
		ax.grid()
		plt.legend(('$x_1$', '$x_6$', '$x_2$', '$x_7$', '$x_3$', '$x_8$',
			'$x_4$', '$x_9$', '$x_5$', '$x_{10}$'),
		           loc='lower right', shadow=True)
		fig.savefig("Figures/states.png")
		plt.show()
Ejemplo n.º 12
0
    def Plant(self,
              T,
              folder,
              A=None,
              B=None,
              C=None,
              F=None,
              K=None,
              L=None,
              x0=None,
              z1=None,
              W=None,
              V=None):
        self.T = T
        if A is None:
            # the vectors are read as rows regardless if they are columns or not
            A = np.loadtxt("Data/" + folder + "/A.txt",
                           delimiter=',',
                           dtype=float)
            B = np.loadtxt("Data/" + folder + "/B.txt",
                           delimiter=',',
                           dtype=float)
            C = np.loadtxt("Data/" + folder + "/C.txt",
                           delimiter=',',
                           dtype=float)
            F = np.loadtxt("Data/" + folder + "/F.txt",
                           delimiter=',',
                           dtype=float)
            K = np.loadtxt("Data/" + folder + "/K.txt",
                           delimiter=',',
                           dtype=float)
            L = np.loadtxt("Data/" + folder + "/L.txt",
                           delimiter=',',
                           dtype=float)
            W = np.loadtxt("Data/" + folder + "/W.txt",
                           delimiter=',',
                           dtype=float)
            V = np.loadtxt("Data/" + folder + "/V.txt",
                           delimiter=',',
                           dtype=float)

        size = np.shape(A)
        if len(size) == 2:
            self.n = size[0]
            if len(size) == 0:
                self.n == 1
        size = np.shape(B)
        if self.n == 1:
            if len(size) == 0:
                self.m = 1
            else:
                self.m = size
        else:
            if len(size) == 2:
                self.m = size[1]
            else:
                if len(size) == 1:
                    self.m = 1
        size = np.shape(C)
        if self.n == 1:
            if len(size) == 0:
                self.p = 1
            else:
                self.p = size
        else:
            if len(size) == 2:
                self.p = size[0]
            else:
                if len(size) == 1:
                    self.p = 1
        A = A.reshape(self.n, self.n)
        B = B.reshape(self.n, self.m)
        C = C.reshape(self.p, self.n)
        K = K.reshape(self.m, self.n)
        L = L.reshape(self.n, self.p)
        self.d, d = np.shape(W)
        self.A = A
        self.B = B
        self.C = C
        self.F = F
        self.K = K
        self.L = L
        self.W = W
        self.V = V

        self.Af = util_fpv.vfp(A)
        self.Bf = util_fpv.vfp(B)
        self.Cf = util_fpv.vfp(C)
        self.Kf = util_fpv.vfp(K)
        self.Lf = util_fpv.vfp(L)
        self.Wf = util_fpv.vfp(W)
        self.Vf = util_fpv.vfp(V)