Hello, i’m trying to test an algorithm to check different chunks of a numpy array to find similarities. I’ve tried by using a whole u16bit number, but the subtraction could cause an underflow into a signed 17 bits. My current approach uses numpy arrays to make it more flexible:
def _create_circuit(self):
"""Create the FHE circuit for comparing arrays of 4-bit values."""
@fhe.compiler({"x": "encrypted", "y": "clear"})
def compare_positions(x, y):
# Assuming x and y are np.uint4 values (0-15)
b_enc = fhe.zeros(y.shape) + y
c = fhe.multivariate(lambda a, b: a % b)(x, b_enc)
return c
# Create representative input arrays for compilation
# Define array size (number of 4-bit elements in each array)
array_size = 4 # Adjust as needed
# Generate sample arrays for inputset
# We'll create arrays with values from 0-15 (4-bit range)
sample_arrays = []
# Add edge cases
sample_arrays.append(np.zeros(array_size, dtype=np.uint8))
sample_arrays.append(np.ones(array_size, dtype=np.uint8) * 15) # Max 4-bit value
# Add arrays with different patterns
sample_arrays.append(np.array([0, 5, 10, 15], dtype=np.uint8))
sample_arrays.append(np.array([15, 10, 5, 0], dtype=np.uint8))
sample_arrays.append(np.array([7, 7, 7, 7], dtype=np.uint8))
# Add some random samples
for _ in range(min(20, self.input_set_size)):
sample = np.random.randint(0, 16, size=array_size, dtype=np.uint8)
sample_arrays.append(sample)
# Create inputset with pairs of arrays
# Limit combinations to keep compilation time reasonable
inputset = [(x, y) for x in sample_arrays for y in sample_arrays[:10]]
print(inputset)
return compare_positions.compile(inputset, self.configuration, show_mlir=False)
this is the way i’m calling the function:
def test_circuit_creation(self):
"""Test that the circuit is created and works correctly."""
# Test the circuit with a simple comparison
pos1_array = self.uint16_to_array(42)
pos2_array = self.uint16_to_array(42)
# Encrypt first position
encrypted_pos1, _ = self.client.encrypt(pos1_array, None)
# Run the circuit
encrypted_result = self.encryption.run_comparison(
encrypted_pos1,
pos2_array,
self.client.evaluation_keys
)
# Decrypt the result
result = self.client.decrypt(encrypted_result)
# Check result - should be all the values from the array should be equal to 0
for i in range(4):
self.assertEqual(result[i], 0,
f"Expected position {i} to be 0, got {result[i]} for positions {pos1_array} and {pos2_array}")
By doing so i get this runtime error which i can’t figure ou the cause:
Traceback (most recent call last):
File "/home/diebbo/Clones/tesi/python/test/test_encryption_functions.py", line 48, in test_circuit_creation
encrypted_result = self.encryption.run_comparison(
File "/home/diebbo/Clones/tesi/python/utils/concrete_encryption.py", line 79, in run_comparison
result = self.circuit.run(
File "/home/diebbo/Clones/tesi/python/lib/python3.8/site-packages/concrete/fhe/compilation/server.py", line 460, in run
simulated_client_circuit.val.simulate_prepare_input(Value_(arg), i)
RuntimeError: bad optional access