Hi and thank you for the response. Hopefully the sample code here is working with the latest version of concrete-numpy.
According to my original issue, still I have some relevant issues:
- you mentioned that
np.newaxis
in indexing is not supported so I have to use reshape here but when I apply reshape on encrypted vector:
AttributeError: 'PublicResult' object has no attribute 'reshape'
- Even for squaring like
squared_residues = residues ** 2
I got error:
TypeError: unsupported operand type(s) for ** or pow(): 'PublicResult' and 'int'
- and I would appreciate it if you could possibly suggest me how I can proceed with addition and subtraction here as input (sample) / inputsets are making troubles and no appropriate results can be achieved so far.
I tried to rewrite the above mentioned code into CNP like this:
def cnp_datamean(self, data):
return np.sum(data) // data.size
def cnp_rowmean(self, data):
return np.sum(data, axis=1) // data.shape[1]
def cnp_colmean(self, data):
return np.sum(data, axis=0) // data.shape[0]
def cnp_add(self, value1, value2):
return value1 + value2
def cnp_square(self, value1):
return value1 ** 2
def cnp_sub(self, value1, value2):
return value1 - value2
def getEnc_mean(self, inputset, data):
compiler = cnp.Compiler(self.cnp_datamean, {"data": "encrypted"})
circuit = compiler.compile(inputset)
data = data.astype('uint8')
print(circuit.encrypt_run_decrypt(data))
circuit.keygen()
public_args = circuit.encrypt(data)
encrypted_datamean = circuit.run(public_args)
return encrypted_datamean
def getEnc_rowmean(self, inputset, data):
compiler = cnp.Compiler(self.cnp_rowmean, {"data": "encrypted"})
circuit = compiler.compile(inputset)
data = data.astype('uint8')
circuit.keygen()
public_args = circuit.encrypt(data)
encrypted_rowmean = circuit.run(public_args)
return encrypted_rowmean
def getEnc_colmean(self, inputset, data):
compiler = cnp.Compiler(self.cnp_colmean, {"data": "encrypted"})
circuit = compiler.compile(inputset)
data = data.astype('uint8')
circuit.keygen()
public_args = circuit.encrypt(data)
encrypted_colmean = circuit.run(public_args)
return encrypted_colmean
def getEnc_subtraction(self, vec1, vec2):
compiler = cnp.Compiler(self.cnp_sub, {"value1": "encrypted", "value2": "encrypted"})
inputset = [
((np.random.randint(0, 30, size=(2, 2)) for _ in range(10)), (np.random.randint(0, 30) for _ in range(10)))
]
circuit = compiler.compile(inputset)
sample = [
(vec1, vec2),
]
# sample = sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_addition = circuit.run(public_args)
return encrypted_addition
def getEnc_addition(self, vec1, vec2):
compiler = cnp.Compiler(self.cnp_add, {"value1": "encrypted", "value2": "encrypted"})
inputset = [
((np.random.randint(0, 30, size=(2, 2)) for _ in range(10)), (np.random.randint(0, 30) for _ in range(10)))
]
circuit = compiler.compile(inputset)
sample = [
(vec1, vec2),
]
# sample = sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_addition = circuit.run(public_args)
return encrypted_addition
def getEnc_square(self, vec1):
compiler = cnp.Compiler(self.cnp_square(), {"value1": "encrypted"})
inputset = [np.random.randint(0, 30, size=(2, 2)) for _ in range(10)]
circuit = compiler.compile(inputset)
sample = [vec1]
# sample = sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_square = circuit.run(public_args)
return encrypted_square
def getEnc_msr(self, squared_residues):
compiler = cnp.Compiler(self.cnp_datamean, {"data": "encrypted"})
inputset = [np.random.randint(0, 30, size=(2, 2)) for _ in range(10)]
circuit = compiler.compile(inputset)
sample = squared_residues
sample = sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_datamean = circuit.run(public_args)
return encrypted_datamean
def getEnc_rowmsr(self, squared_residues):
compiler = cnp.Compiler(self.cnp_rowmean, {"data": "encrypted"})
inputset = [np.random.randint(0, 30, size=(2, 2)) for _ in range(10)]
circuit = compiler.compile(inputset)
sample = squared_residues
sample= sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_rowmean = circuit.run(public_args)
return encrypted_rowmean
def getEnc_colmsr(self, squared_residues):
compiler = cnp.Compiler(self.cnp_colmean, {"data": "encrypted"})
inputset = [np.random.randint(0, 30, size=(2, 2)) for _ in range(10)]
circuit = compiler.compile(inputset)
sample = squared_residues
sample = sample.astype(int)
circuit.keygen()
public_args = circuit.encrypt(sample)
encrypted_colmean = circuit.run(public_args)
return encrypted_colmean
def _calculate_msr(self, data, rows, cols):
"""Calculate the mean squared residues of the rows, of the columns and of the full data matrix."""
sub_data = data[rows][:, cols]
inputset = [np.random.randint(0, 30, size=(2, 2)) for _ in range(10)]
data_mean = self.getEnc_mean(inputset, sub_data)
row_means = self.getEnc_rowmean(inputset, sub_data)
col_means = self.getEnc_colmean(inputset, sub_data)
row_means = row_means.reshape((sub_data.shape[0], 1))
residues_p1 = self.getEnc_subtraction(sub_data, row_means)
residues_p2 = self.getEnc_addition(col_means, data_mean)
residues = self.getEnc_subtraction(residues_p1, residues_p2)
squared_residues = self.getEnc_square(residues)
msr = self.getEnc_msr(squared_residues)
row_msr = self.getEnc_rowmsr(squared_residues)
col_msr = self.getEnc_colmsr(squared_residues)
return msr, row_msr, col_msr