Today, we are announcing the release of Concrete-core V1.0.0-beta, getting one step closer towards the 1.0.0 release. This beta version introduces:
New public engines and entities, implemented in the Core backend, in particular:
- The packing keyswitch, which makes it possible to transform a vector of LWE ciphertexts into a single GLWE ciphertext.
- The encryption of GGSW ciphertexts.
- The external product between a GGSW ciphertext and a GLWE ciphertext.
- Engines to add and subtract ciphertexts or ciphertext vectors in fuse/discard mode (you can find more information about the fuse/discard wording in the user documentation).
- Engines for trivial encryption and decryption.
- Engines to convert GGSW and GLWE ciphertexts from the standard to the Fourier domain.
Two new companion libraries:
- Concrete-core-fixture: contains generic fixtures for the Concrete-core engines. It makes it possible to sample and test any implementation of an engine trait.
- Concrete-core-test: uses the generic fixtures to systematically test the engines for any backend.
In this post, we are introducing the new fixture and test crates. Check our tutorial to see how to set up the testing of a new backend implementation!
Simplifying the testing of new accelerators and backend implementations
The fixture and test crates are built to support any backend. To this purpose, the sampling and testing of engines is split into several steps:
- Generate prototype values: at this stage all the necessary data to run an engine is produced, using the `CoreEngine`. There are two types of prototypes:
- Repetition prototypes: data that is reused a certain amount of times to generate batches of samples for testing. The idea is to use a relatively small number of repetitions, in order to keep computational times as low as possible. For instance, for the bootstrapping test we generate 10 bootstrapping keys and reuse them for multiple tests.
- Sample prototypes: data that is generated repeatedly for each repetition value, a large number of times (for example one thousand times).
- Synthesize the prototypes: once the necessary data to run an engine has been produced, it has to be converted to the appropriate type (for example, for a GPU backend it has to be copied to the GPU): this is where the synthesis stage intervenes. When testing a new backend, there are few things to implement: the synthesis stage is one of them.
- Run the engine: the engine that the fixture is related to is executed.
- Process the results: convert them back to types compatible with the `CoreEngine`, and destroy the entities that have undergone synthesis. This is necessary to ensure that there are no memory leaks related to the allocation of data via a dependency of Concrete-core (for example a C++ library for the GPU acceleration of TFHE).
- Verify the results: this is where the test is executed (for example a noise distribution test).
The test crate relies on the fixture crate, and simply defines what fixtures are used, with which precision of the integer representation, and for which backends. This is illustrated in the figure below: the fixture crate relies on the specification of Concrete-core, and Concrete-core-test instantiates the fixtures for specific backends (the Core one in the figure).
These two new libraries, in addition to the existing crate dedicated to benchmarking, enable you to quickly test and compare the performance of a new implementation with the available implementations. It is now simpler than ever to deliver hardware acceleration for FHE.
With this beta version of the 1.0.0 version of Concrete-core, we’re supporting more cryptographic operations in the Core backend, and a new testing facility to ease the integration of hardware accelerations. It is now easier than ever to add new implementations and accelerations into Concrete-core. If you’d like to be part of this adventure, check out our tutorials and start a pull request!