Today, we are announcing the release of a new version of Concrete Numpy.
Concrete Numpy is an open-source set of tools which aims to simplify the use of fully homomorphic encryption (FHE) for data scientists. It can be used to implement machine learning models using a subset of numpy that compiles to FHE. Data scientists are able to train models with popular machine learning libraries and then convert the prediction functions of these models, written in numpy, to FHE.
This new version of Concrete Numpy v0.5 comes with many features:
Still built on the efficiency, usability, and simplicity of the Concrete library, this new version of concrete-numpy brings explicit encrypt, decrypt, and run support:
import concrete.numpy as hnp
import numpy as np
def f(x):
return np.sum(x)
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(3, 2)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[3, 2],
[4, 1],
[3, 7],
],
)
output = circuit.run(input.astype(np.uint8))
expected_output = 20
assert output == expected_output import concrete.numpy as hnp
import numpy as np
def f(x):
return np.concatenate((x, x + 1))
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(2, 2)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[3, 3],
[7, 0],
],
)
output = circuit.run(input.astype(np.uint8))
expected_output = np.array(
[
[3, 3],
[7, 0],
[4, 4],
[8, 1],
],
)
assert np.array_equal(output, expected_output)import concrete.numpy as hnp
import numpy as np
def f(x):
return hnp.conv2d(x, np.array([[2, 1], [3, 2]]).reshape(1, 1, 2, 2))
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(1, 1, 4, 4)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[3, 2, 1, 0],
[3, 2, 1, 0],
[3, 2, 1, 0],
[3, 2, 1, 0],
]
).reshape(1, 1, 4, 4)
output = circuit.run(input.astype(np.uint8))import concrete.numpy as hnp
import numpy as np
def f(x):
return np.matmul(x, np.array([[2, 1], [3, 2]]))
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(2, 3, 2)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[
[3, 2],
[4, 1],
[3, 7],
],
[
[2, 3],
[1, 4],
[7, 3],
],
]
)
output = circuit.run(input.astype(np.uint8))
expected_output = np.array(
[
[
[12, 7],
[11, 6],
[27, 17],
],
[
[13, 8],
[14, 9],
[23, 13],
],
],
)
assert np.array_equal(output, expected_output)import concrete.numpy as hnp
import numpy as np
def f(x):
return np.transpose(x)
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(3, 2)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[3, 2],
[4, 1],
[3, 7],
],
)
output = circuit.run(input.astype(np.uint8))
expected_output = np.array(
[
[3, 4, 3],
[2, 1, 7],
],
)
assert np.array_equal(output, expected_output)import concrete.numpy as hnp
import numpy as np
def f(x):
return x + 100
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = range(100)
circuit = compiler.compile_on_inputset(inputset)
input = 50
output = circuit.run(input)
expected_output = 150
assert output == expected_outputBefore this version, the concrete-compiler parallelism infrastructure was not exposed to concrete-numpy, but with this new release, the loop parallelism is exposed (by default) to concrete-numpy.
- `run` has now been replaced by `encrypt_run_decrypt` in compiled circuits (`FHECircuit`).
- Separate API for doing key generation, encryption, decryption, and execution.
import concrete.numpy as hnp
import numpy as np
def f(x):
return np.sum(x)
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
inputset = [np.random.randint(0, 2 ** 3, size=(3, 2)) for _ in range(10)]
circuit = compiler.compile_on_inputset(inputset)
input = np.array(
[
[3, 2],
[4, 1],
[3, 7],
], dtype=np.uint8
)
circuit.keygen()
public_arguments = circuit.encrypt(input)
encrypted_result = circuit.run(public_arguments)
output = circuit.decrypt(encrypted_result)
News, research and product releases