mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-19 08:54:26 -05:00
enhance(runtime): Fix the runtime tools to handle the ciphertext bufferization and the new compiler concrete bufferized API
This commit is contained in:
committed by
Quentin Bourgerie
parent
8a9cce64e3
commit
4e8a9d1077
@@ -6,31 +6,20 @@
|
||||
#include "concretelang/ClientLib/KeySet.h"
|
||||
#include "concretelang/Support/Error.h"
|
||||
|
||||
#define CAPI_ERR_TO_LLVM_ERROR(s, msg) \
|
||||
{ \
|
||||
int err; \
|
||||
s; \
|
||||
if (err != 0) { \
|
||||
return llvm::make_error<llvm::StringError>( \
|
||||
msg, llvm::inconvertibleErrorCode()); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace mlir {
|
||||
namespace concretelang {
|
||||
|
||||
KeySet::~KeySet() {
|
||||
int err;
|
||||
for (auto it : secretKeys) {
|
||||
free_lwe_secret_key_u64(&err, it.second.second);
|
||||
free_lwe_secret_key_u64(it.second.second);
|
||||
}
|
||||
for (auto it : bootstrapKeys) {
|
||||
free_lwe_bootstrap_key_u64(&err, it.second.second);
|
||||
free_lwe_bootstrap_key_u64(it.second.second);
|
||||
}
|
||||
for (auto it : keyswitchKeys) {
|
||||
free_lwe_keyswitch_key_u64(&err, it.second.second);
|
||||
free_lwe_keyswitch_key_u64(it.second.second);
|
||||
}
|
||||
free_encryption_generator(&err, encryptionRandomGenerator);
|
||||
free_encryption_generator(encryptionRandomGenerator);
|
||||
}
|
||||
|
||||
llvm::Expected<std::unique_ptr<KeySet>>
|
||||
@@ -97,10 +86,8 @@ llvm::Error KeySet::setupEncryptionMaterial(ClientParameters ¶ms,
|
||||
}
|
||||
}
|
||||
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
this->encryptionRandomGenerator =
|
||||
allocate_encryption_generator(&err, seed_msb, seed_lsb),
|
||||
"cannot allocate encryption generator");
|
||||
this->encryptionRandomGenerator =
|
||||
allocate_encryption_generator(seed_msb, seed_lsb);
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
@@ -108,13 +95,11 @@ llvm::Error KeySet::setupEncryptionMaterial(ClientParameters ¶ms,
|
||||
llvm::Error KeySet::generateKeysFromParams(ClientParameters ¶ms,
|
||||
uint64_t seed_msb,
|
||||
uint64_t seed_lsb) {
|
||||
|
||||
{
|
||||
// Generate LWE secret keys
|
||||
SecretRandomGenerator *generator;
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
generator = allocate_secret_generator(&err, seed_msb, seed_lsb),
|
||||
"cannot allocate random generator");
|
||||
|
||||
generator = allocate_secret_generator(seed_msb, seed_lsb);
|
||||
for (auto secretKeyParam : params.secretKeys) {
|
||||
auto e = this->generateSecretKey(secretKeyParam.first,
|
||||
secretKeyParam.second, generator);
|
||||
@@ -122,14 +107,12 @@ llvm::Error KeySet::generateKeysFromParams(ClientParameters ¶ms,
|
||||
return std::move(e);
|
||||
}
|
||||
}
|
||||
CAPI_ERR_TO_LLVM_ERROR(free_secret_generator(&err, generator),
|
||||
"cannot free random generator");
|
||||
free_secret_generator(generator);
|
||||
}
|
||||
// Allocate the encryption random generator
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
this->encryptionRandomGenerator =
|
||||
allocate_encryption_generator(&err, seed_msb, seed_lsb),
|
||||
"cannot allocate encryption generator");
|
||||
|
||||
this->encryptionRandomGenerator =
|
||||
allocate_encryption_generator(seed_msb, seed_lsb);
|
||||
// Generate bootstrap and keyswitch keys
|
||||
{
|
||||
for (auto bootstrapKeyParam : params.bootstrapKeys) {
|
||||
@@ -170,12 +153,9 @@ llvm::Error KeySet::generateSecretKey(LweSecretKeyID id,
|
||||
LweSecretKeyParam param,
|
||||
SecretRandomGenerator *generator) {
|
||||
LweSecretKey_u64 *sk;
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
sk = allocate_lwe_secret_key_u64(&err, {param.size + 1}),
|
||||
"cannot allocate secret key");
|
||||
sk = allocate_lwe_secret_key_u64({param.size});
|
||||
|
||||
CAPI_ERR_TO_LLVM_ERROR(fill_lwe_secret_key_u64(&err, sk, generator),
|
||||
"cannot fill secret key with random generator");
|
||||
fill_lwe_secret_key_u64(sk, generator);
|
||||
|
||||
secretKeys[id] = {param, sk};
|
||||
|
||||
@@ -207,11 +187,9 @@ llvm::Error KeySet::generateBootstrapKey(BootstrapKeyID id,
|
||||
|
||||
uint64_t polynomialSize = total_dimension / param.glweDimension;
|
||||
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
bsk = allocate_lwe_bootstrap_key_u64(
|
||||
&err, {param.level}, {param.baseLog}, {param.glweDimension + 1},
|
||||
{inputSk->second.first.size + 1}, {polynomialSize}),
|
||||
"cannot allocate bootstrap key");
|
||||
bsk = allocate_lwe_bootstrap_key_u64(
|
||||
{param.level}, {param.baseLog}, {param.glweDimension},
|
||||
{inputSk->second.first.size}, {polynomialSize});
|
||||
|
||||
// Store the bootstrap key
|
||||
bootstrapKeys[id] = {param, bsk};
|
||||
@@ -219,23 +197,16 @@ llvm::Error KeySet::generateBootstrapKey(BootstrapKeyID id,
|
||||
// Convert the output lwe key to glwe key
|
||||
GlweSecretKey_u64 *glwe_sk;
|
||||
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
glwe_sk = allocate_glwe_secret_key_u64(&err, {param.glweDimension + 1},
|
||||
{polynomialSize}),
|
||||
"cannot allocate glwe key for initiliazation of bootstrap key");
|
||||
glwe_sk =
|
||||
allocate_glwe_secret_key_u64({param.glweDimension}, {polynomialSize});
|
||||
|
||||
CAPI_ERR_TO_LLVM_ERROR(fill_glwe_secret_key_with_lwe_secret_key_u64(
|
||||
&err, glwe_sk, outputSk->second.second),
|
||||
"cannot fill glwe key with big key");
|
||||
fill_glwe_secret_key_with_lwe_secret_key_u64(glwe_sk,
|
||||
outputSk->second.second);
|
||||
|
||||
// Initialize the bootstrap key
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
fill_lwe_bootstrap_key_u64(&err, bsk, inputSk->second.second, glwe_sk,
|
||||
generator, {param.variance}),
|
||||
"cannot fill bootstrap key");
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
free_glwe_secret_key_u64(&err, glwe_sk),
|
||||
"cannot free glwe key for initiliazation of bootstrap key")
|
||||
fill_lwe_bootstrap_key_u64(bsk, inputSk->second.second, glwe_sk, generator,
|
||||
{param.variance});
|
||||
free_glwe_secret_key_u64(glwe_sk);
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
@@ -257,33 +228,32 @@ llvm::Error KeySet::generateKeyswitchKey(KeyswitchKeyID id,
|
||||
}
|
||||
// Allocate the keyswitch key
|
||||
LweKeyswitchKey_u64 *ksk;
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
ksk = allocate_lwe_keyswitch_key_u64(&err, {param.level}, {param.baseLog},
|
||||
{inputSk->second.first.size + 1},
|
||||
{outputSk->second.first.size + 1}),
|
||||
"cannot allocate keyswitch key");
|
||||
|
||||
ksk = allocate_lwe_keyswitch_key_u64({param.level}, {param.baseLog},
|
||||
{inputSk->second.first.size},
|
||||
{outputSk->second.first.size});
|
||||
|
||||
// Store the keyswitch key
|
||||
keyswitchKeys[id] = {param, ksk};
|
||||
// Initialize the keyswitch key
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
fill_lwe_keyswitch_key_u64(&err, ksk, inputSk->second.second,
|
||||
outputSk->second.second, generator,
|
||||
{param.variance}),
|
||||
"cannot fill bootsrap key");
|
||||
|
||||
fill_lwe_keyswitch_key_u64(ksk, inputSk->second.second,
|
||||
outputSk->second.second, generator,
|
||||
{param.variance});
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
llvm::Error KeySet::allocate_lwe(size_t argPos,
|
||||
LweCiphertext_u64 **ciphertext) {
|
||||
llvm::Error KeySet::allocate_lwe(size_t argPos, uint64_t **ciphertext,
|
||||
uint64_t &size) {
|
||||
if (argPos >= inputs.size()) {
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
"allocate_lwe position of argument is too high",
|
||||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
auto inputSk = inputs[argPos];
|
||||
CAPI_ERR_TO_LLVM_ERROR(*ciphertext = allocate_lwe_ciphertext_u64(
|
||||
&err, {std::get<1>(inputSk).size + 1}),
|
||||
"cannot allocate ciphertext");
|
||||
|
||||
size = std::get<1>(inputSk).size + 1;
|
||||
*ciphertext = (uint64_t *)malloc(sizeof(uint64_t) * size);
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
@@ -297,7 +267,7 @@ bool KeySet::isOutputEncrypted(size_t argPos) {
|
||||
std::get<0>(outputs[argPos]).encryption.hasValue();
|
||||
}
|
||||
|
||||
llvm::Error KeySet::encrypt_lwe(size_t argPos, LweCiphertext_u64 *ciphertext,
|
||||
llvm::Error KeySet::encrypt_lwe(size_t argPos, uint64_t *ciphertext,
|
||||
uint64_t input) {
|
||||
if (argPos >= inputs.size()) {
|
||||
return llvm::make_error<llvm::StringError>(
|
||||
@@ -311,19 +281,15 @@ llvm::Error KeySet::encrypt_lwe(size_t argPos, LweCiphertext_u64 *ciphertext,
|
||||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
// Encode - TODO we could check if the input value is in the right range
|
||||
Plaintext_u64 plaintext = {
|
||||
input << (64 -
|
||||
(std::get<0>(inputSk).encryption->encoding.precision + 1))};
|
||||
// Encrypt
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
encrypt_lwe_u64(&err, std::get<2>(inputSk), ciphertext, plaintext,
|
||||
encryptionRandomGenerator,
|
||||
{std::get<0>(inputSk).encryption->variance}),
|
||||
"cannot encrypt");
|
||||
uint64_t plaintext =
|
||||
input << (64 - (std::get<0>(inputSk).encryption->encoding.precision + 1));
|
||||
encrypt_lwe_u64(std::get<2>(inputSk), ciphertext, plaintext,
|
||||
encryptionRandomGenerator,
|
||||
{std::get<0>(inputSk).encryption->variance});
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
llvm::Error KeySet::decrypt_lwe(size_t argPos, LweCiphertext_u64 *ciphertext,
|
||||
llvm::Error KeySet::decrypt_lwe(size_t argPos, uint64_t *ciphertext,
|
||||
uint64_t &output) {
|
||||
|
||||
if (argPos >= outputs.size()) {
|
||||
@@ -337,14 +303,10 @@ llvm::Error KeySet::decrypt_lwe(size_t argPos, LweCiphertext_u64 *ciphertext,
|
||||
"decrypt_lwe: the positional argument is not encrypted",
|
||||
llvm::inconvertibleErrorCode());
|
||||
}
|
||||
// Decrypt
|
||||
Plaintext_u64 plaintext = {0};
|
||||
CAPI_ERR_TO_LLVM_ERROR(
|
||||
decrypt_lwe_u64(&err, std::get<2>(outputSk), ciphertext, &plaintext),
|
||||
"cannot decrypt");
|
||||
uint64_t plaintext = decrypt_lwe_u64(std::get<2>(outputSk), ciphertext);
|
||||
// Decode
|
||||
size_t precision = std::get<0>(outputSk).encryption->encoding.precision;
|
||||
output = plaintext._0 >> (64 - precision - 2);
|
||||
output = plaintext >> (64 - precision - 2);
|
||||
size_t carry = output % 2;
|
||||
output = ((output >> 1) + carry) % (1 << (precision + 1));
|
||||
return llvm::Error::success();
|
||||
|
||||
Reference in New Issue
Block a user