Default backend

Default backend

The default backend contains the CPU implementation of the majority of the engines from the specification. It is totally LLVM compatible, which makes it lightweight and very portable.


Some additional features can be activated on top of the default backend:
  • seeder_unix and seeder_x86_64_rdseed make it possible to use a seeder based on the Unix system or relying on rdseed acceleration, which is a feature of (some) x86_64 platforms.
  • backend_default_generator_x86_64_aesni: makes it possible to generate randoms relying on aesni acceleration (a feature present on most modern x86_64 platforms) instead of the much slower software generation (that's activated by default).
  • backend_default_parallel: activates the creation of bootstrap keys with multithreading (relying on the rayon dependency).
  • backend_default_serialization: activates the compilation of serialization features in the default backend.


In the tutorials we do not try to build a "real life" use case: beware that the parameters used throughout the tutorials are not secure, and may not produce decrypted results that are unaffected by the noise! Higher level crates, built on top of concrete-core, will be released and make it possible to use concrete-core more easily.
In this first tutorial we'll just see how to create secret keys for LWE and GLWE ciphertexts, and a bootstrap key. More advanced tutorials can be found in the FFTW backend and Cuda backend pages.
Here we'll just set up a new project containing a Cargo.toml file, and an src directory with a file. The Cargo.toml file should contain:
name = "tutorial"
version = "0.1.0"
edition = "2021"
concrete-core = {version = "=1.0.0-delta", features=["backend_default", "backend_default_parallel"]}
concrete-csprng = {version = "=0.2.0"}
So we can use concrete-core version 1.0.0-gamma as a dependency. Then, in the file we're going to:
  • import the necessary types and functions:
use concrete_core::prelude::Variance;
use concrete_core::prelude::{GlweDimension, PolynomialSize};
use concrete_core::prelude::*;
  • set up some cryptographic parameters (recall that the parameters chosen here do not guarantee any security, neither to produce a result unaffected by the noise)
  • create the engines we need for the key creation
  • create the keys themselves
  • destroy the content of the keys
fn main() {
// 1. Set up cryptographic parameters
// DISCLAIMER: the parameters used here are only for test purpose, and are not secure.
let (lwe_dim, glwe_dim, poly_size) = (
let (dec_lc, dec_bl) = (DecompositionLevelCount(3), DecompositionBaseLog(5));
let noise = Variance(2_f64.powf(-60.));
// 2. Create the necessary engines
// Here we need to create a secret to give to the unix seeder, but we skip the actual secret creation
const UNSAFE_SECRET: u128 = 0;
let mut engine = DefaultEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET))).unwrap();
let mut parallel_engine = DefaultParallelEngine::new(Box::new(UnixSeeder::new(UNSAFE_SECRET))).unwrap();
// 3. Create the keys
let lwe_sk: LweSecretKey64 = engine.generate_new_lwe_secret_key(lwe_dim).unwrap();
let glwe_sk: GlweSecretKey64 = engine.generate_new_glwe_secret_key(glwe_dim, poly_size).unwrap();
// The bootstrap key is created with multithreading, relying on rayon
let bsk: LweBootstrapKey64 =
parallel_engine.generate_new_lwe_bootstrap_key(&lwe_sk, &glwe_sk, dec_bl, dec_lc, noise).unwrap();
// 4. Finally, destroy all data
// Destroying the secret keys is important since their content is reset to 0 before dropping
// memory, to defend against potential attacks
// The bootstrap key is public, so it is not as critical to destroy it
In this example, you can see that the bootstrap key was created with a DefaultParallelEngine, in order to accelerate computation via multithreading.
To execute this code, simply run:
cargo run --release
The full list of engines and entities implemented in the default backend is available in the Rust documentation.
Export as PDF
Copy link
On this page
Default backend