// Part of the Concrete Compiler Project, under the BSD3 License with Zama // Exceptions. See // https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt // for license information. #include "concretelang/Common/Keys.h" #include "capnp/any.h" #include "concrete-cpu.h" #include "concrete-protocol.capnp.h" #include "concretelang/Common/Csprng.h" #include "concretelang/Common/Protocol.h" #include #include #include #include using concretelang::csprng::CSPRNG; using concretelang::protocol::Message; using concretelang::protocol::protoPayloadToSharedVector; using concretelang::protocol::vectorToProtoPayload; namespace concretelang { namespace keys { template Message keyToProto(const Key &key) { Message output; auto proto = output.asBuilder(); proto.setInfo(key.getInfo().asReader()); proto.setPayload(vectorToProtoPayload(key.getBuffer()).asReader()); return std::move(output); } LweSecretKey::LweSecretKey(Message info, CSPRNG &csprng) { // Allocate the buffer buffer = std::make_shared>( info.asReader().getParams().getLweDimension()); // We copy the informations. this->info = info; #ifdef CONCRETELANG_GENERATE_UNSECURE_SECRET_KEYS // In insecure debug mode, the secret key is filled with zeros. getApproval(); std::fill(buffer->begin(), buffer->end(), 0); #else // Initialize the lwe secret key buffer concrete_cpu_init_secret_key_u64( buffer->data(), info.asReader().getParams().getLweDimension(), csprng.ptr, csprng.vtable); #endif } LweSecretKey LweSecretKey::fromProto(const Message &proto) { auto info = Message(proto.asReader().getInfo()); auto vector = protoPayloadToSharedVector(proto.asReader().getPayload()); return LweSecretKey(vector, info); } Message LweSecretKey::toProto() const { return keyToProto(*this); } const uint64_t *LweSecretKey::getRawPtr() const { return this->buffer->data(); } size_t LweSecretKey::getSize() const { return this->buffer->size(); } const Message & LweSecretKey::getInfo() const { return this->info; } const std::vector &LweSecretKey::getBuffer() const { return *this->buffer; } LweBootstrapKey::LweBootstrapKey( Message info, const LweSecretKey &inputKey, const LweSecretKey &outputKey, CSPRNG &csprng) { assert(info.asReader().getCompression() == concreteprotocol::Compression::NONE); assert(inputKey.info.asReader().getParams().getLweDimension() == info.asReader().getParams().getInputLweDimension()); assert(outputKey.info.asReader().getParams().getLweDimension() == info.asReader().getParams().getGlweDimension() * info.asReader().getParams().getPolynomialSize()); // Allocate the buffer auto params = info.asReader().getParams(); auto bufferSize = concrete_cpu_bootstrap_key_size_u64( params.getLevelCount(), params.getGlweDimension(), params.getPolynomialSize(), params.getInputLweDimension()); buffer = std::make_shared>(); (*buffer).resize(bufferSize); // We copy the informations. this->info = info; // Initialize the keyswitch key buffer concrete_cpu_init_lwe_bootstrap_key_u64( buffer->data(), inputKey.buffer->data(), outputKey.buffer->data(), params.getInputLweDimension(), params.getPolynomialSize(), params.getGlweDimension(), params.getLevelCount(), params.getBaseLog(), params.getVariance(), Parallelism::Rayon, csprng.ptr, csprng.vtable); }; LweBootstrapKey LweBootstrapKey::fromProto( const Message &proto) { assert(proto.asReader().getInfo().getCompression() == concreteprotocol::Compression::NONE); auto info = Message( proto.asReader().getInfo()); auto vector = protoPayloadToSharedVector(proto.asReader().getPayload()); return LweBootstrapKey(vector, info); } Message LweBootstrapKey::toProto() const { return keyToProto( *this); } const uint64_t *LweBootstrapKey::getRawPtr() const { return this->buffer->data(); } size_t LweBootstrapKey::getSize() const { return this->buffer->size(); } const Message & LweBootstrapKey::getInfo() const { return this->info; } const std::vector &LweBootstrapKey::getBuffer() const { return *this->buffer; } LweKeyswitchKey::LweKeyswitchKey( Message info, const LweSecretKey &inputKey, const LweSecretKey &outputKey, CSPRNG &csprng) { assert(info.asReader().getCompression() == concreteprotocol::Compression::NONE); assert(inputKey.info.asReader().getParams().getLweDimension() == info.asReader().getParams().getInputLweDimension()); assert(outputKey.info.asReader().getParams().getLweDimension() == info.asReader().getParams().getOutputLweDimension()); // Allocate the buffer auto params = info.asReader().getParams(); auto bufferSize = concrete_cpu_keyswitch_key_size_u64( params.getLevelCount(), params.getBaseLog(), params.getInputLweDimension(), params.getOutputLweDimension()); buffer = std::make_shared>(); (*buffer).resize(bufferSize); // We copy the informations. this->info = info; // Initialize the keyswitch key buffer concrete_cpu_init_lwe_keyswitch_key_u64( buffer->data(), inputKey.buffer->data(), outputKey.buffer->data(), params.getInputLweDimension(), params.getOutputLweDimension(), params.getLevelCount(), params.getBaseLog(), params.getVariance(), csprng.ptr, csprng.vtable); } LweKeyswitchKey LweKeyswitchKey::fromProto( const Message &proto) { assert(proto.asReader().getInfo().getCompression() == concreteprotocol::Compression::NONE); auto info = Message( proto.asReader().getInfo()); auto vector = protoPayloadToSharedVector(proto.asReader().getPayload()); return LweKeyswitchKey(vector, info); } Message LweKeyswitchKey::toProto() const { return keyToProto( *this); } const uint64_t *LweKeyswitchKey::getRawPtr() const { return this->buffer->data(); } size_t LweKeyswitchKey::getSize() const { return this->buffer->size(); } const Message & LweKeyswitchKey::getInfo() const { return this->info; } const std::vector &LweKeyswitchKey::getBuffer() const { return *this->buffer; } PackingKeyswitchKey::PackingKeyswitchKey( Message info, const LweSecretKey &inputKey, const LweSecretKey &outputKey, CSPRNG &csprng) { assert(info.asReader().getCompression() == concreteprotocol::Compression::NONE); assert(info.asReader().getParams().getGlweDimension() * info.asReader().getParams().getPolynomialSize() == outputKey.info.asReader().getParams().getLweDimension()); // Allocate the buffer auto params = info.asReader().getParams(); auto bufferSize = concrete_cpu_lwe_packing_keyswitch_key_size( params.getGlweDimension(), params.getPolynomialSize(), params.getLevelCount(), params.getInputLweDimension()) * (params.getGlweDimension() + 1); buffer = std::make_shared>(); (*buffer).resize(bufferSize); // We copy the informations. this->info = info; // Initialize the keyswitch key buffer concrete_cpu_init_lwe_circuit_bootstrap_private_functional_packing_keyswitch_keys_u64( buffer->data(), inputKey.buffer->data(), outputKey.buffer->data(), params.getInputLweDimension(), params.getPolynomialSize(), params.getGlweDimension(), params.getLevelCount(), params.getBaseLog(), params.getVariance(), Parallelism::Rayon, csprng.ptr, csprng.vtable); } PackingKeyswitchKey PackingKeyswitchKey::fromProto( const Message &proto) { assert(proto.asReader().getInfo().getCompression() == concreteprotocol::Compression::NONE); auto info = Message( proto.asReader().getInfo()); auto vector = protoPayloadToSharedVector(proto.asReader().getPayload()); return PackingKeyswitchKey(vector, info); } Message PackingKeyswitchKey::toProto() const { return keyToProto(*this); } const uint64_t *PackingKeyswitchKey::getRawPtr() const { return this->buffer->data(); } size_t PackingKeyswitchKey::getSize() const { return this->buffer->size(); } const Message & PackingKeyswitchKey::getInfo() const { return this->info; } const std::vector &PackingKeyswitchKey::getBuffer() const { return *this->buffer; } } // namespace keys } // namespace concretelang