Thank you for your timely reply😃
This is my implementation of 8-bit binary multiplication using plaintext.
#Convert the input to a binary array.
import numpy as np
input1 = 200
input2 = 222
binary_input1 = np.unpackbits(np.array([input1], dtype=np.uint8))
binary_input2 = np.unpackbits(np.array([input2], dtype=np.uint8))
binary_input1=binary_input1[::-1]
binary_input2=binary_input2[::-1]
print(binary_input1)
print(binary_input2)
[0 0 0 1 0 0 1 1]
[0 1 1 1 1 0 1 1]
#Create an n * 2n matrix to store the result of the multiplication.
n = 8
matrix = np.zeros((n, 2*n), dtype=np.uint8)
print(matrix)
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
#Perform the multiplication.
for i in range(n):
for j in range(n):
matrix[i,i+j] = binary_input1[j] & binary_input2[i]
print(matrix)
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0]
[0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0]]
#reduce_add
def reduce_add(a, b, size):
sum = [0] * size
sum[0]=np.bitwise_xor(a[0],b[0])
carry = np.bitwise_and(a[0],b[0])
for i in range(1,size):
tmp_s=np.bitwise_xor(a[i],b[i])
tmp_c=np.bitwise_and(a[i],b[i])
sum[i]=np.bitwise_xor(tmp_s,carry)
carry=np.bitwise_or(np.bitwise_and(tmp_s,carry),tmp_c)
return sum
result=[0]*2*n
for i in range(n):
result=reduce_add(result,matrix[i],2*n)
result=result[::-1]
print(result)
[1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0]
Below is the encryption circuit implemented using the Concrete library for the same method.
from concrete import fhe
@fhe.circuit({"binary_input1": "encrypted","binary_input2": "encrypted"})
def circuit2(binary_input1: fhe.tensor[fhe.uint2, 8, ],binary_input2: fhe.tensor[fhe.uint2, 8, ]):
n = 8
matrix = np.zeros((n, 2*n), dtype=np.object)
result=[0]*2*n
for i in range(n):
for j in range(n):
matrix[i,i+j] = np.bitwise_and(binary_input1[j],binary_input2[i])
for i in range(n):
result=reduce_add(result,matrix[i],2*n)
return matrix
enc=circuit2.encrypt(result,binary_input1,binary_input2)
res_enc=circuit2.run(enc)
result=circuit2.decrypt(res_enc)
print(result)
I will encounter the following error due to issues with the return value😢
ValueError: Function 'circuit2' returned '[[<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1ed910>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29abfa2fd0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bce15e0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bcdbb20>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bcdb100>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1b98e0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1b92e0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1df790> 0 0 0 0 0
0 0 0]
[0 <concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1eab50>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bcdc340>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac22f9a0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac22f220>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac2993d0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1fd3d0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc3d1f0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1db640> 0 0 0 0 0
0 0]
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1e02e0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f29ac1dea30>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc3f310>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc3f070>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc38970>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc5dfd0>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc2a550>
<concrete.fhe.tracing.tracer.Tracer object at 0x7f292bc2af40> 0]]', which is not supported
I feel that my binary encoding method may not be well-suited for concrete. I would greatly appreciate it if you could provide a detailed description of your approach.