// Part of the Concrete Compiler Project, under the BSD3 License with Zama // Exceptions. See // https://github.com/zama-ai/concrete-compiler-internal/blob/master/LICENSE.txt // for license information. #ifndef CONCRETELANG_CLIENTLIB_CLIENT_LAMBDA_H #define CONCRETELANG_CLIENTLIB_CLIENT_LAMBDA_H #include #include "concretelang/ClientLib/ClientParameters.h" #include "concretelang/ClientLib/EncryptedArguments.h" #include "concretelang/ClientLib/KeySet.h" #include "concretelang/ClientLib/KeySetCache.h" #include "concretelang/ClientLib/PublicArguments.h" #include "concretelang/ClientLib/Types.h" #include "concretelang/Common/Error.h" namespace concretelang { namespace clientlib { using concretelang::error::StringError; using scalar_in = uint8_t; using scalar_out = uint64_t; using tensor1_in = std::vector; using tensor2_in = std::vector>; using tensor3_in = std::vector>>; using tensor1_out = std::vector; using tensor2_out = std::vector>; using tensor3_out = std::vector>>; class ClientLambda { /// Low-level class to create the client side view of a FHE function. public: virtual ~ClientLambda() = default; /// Construct a ClientLambda from a ClientParameter file. static outcome::checked load(std::string funcName, std::string jsonPath); /// Generate or get from cache a KeySet suitable for this ClientLambda outcome::checked, StringError> keySet(std::shared_ptr optionalCache, uint64_t seed_msb, uint64_t seed_lsb); outcome::checked, StringError> decryptReturnedValues(KeySet &keySet, PublicResult &result); outcome::checked decryptReturnedScalar(KeySet &keySet, PublicResult &result); outcome::checked decryptReturnedTensor1(KeySet &keySet, PublicResult &result); outcome::checked decryptReturnedTensor2(KeySet &keySet, PublicResult &result); outcome::checked decryptReturnedTensor3(KeySet &keySet, PublicResult &result); public: ClientParameters clientParameters; }; template outcome::checked topLevelDecryptResult(ClientLambda &lambda, KeySet &keySet, PublicResult &result); template class TypedClientLambda : public ClientLambda { public: static outcome::checked, StringError> load(std::string funcName, std::string jsonPath) { OUTCOME_TRY(auto lambda, ClientLambda::load(funcName, jsonPath)); return TypedClientLambda(lambda); } /// Emit a call on this lambda to a binary ostream. /// The ostream is responsible for transporting the call to a /// ServerLambda::real_call_write function. ostream must be in binary mode /// std::ios_base::openmode::binary outcome::checked serializeCall(Args... args, KeySet &keySet, std::ostream &ostream) { OUTCOME_TRY(auto publicArguments, publicArguments(args..., keySet)); return publicArguments->serialize(ostream); } outcome::checked, StringError> publicArguments(Args... args, KeySet &keySet) { OUTCOME_TRY(auto clientArguments, EncryptedArguments::create(keySet, args...)); return clientArguments->exportPublicArguments(clientParameters, keySet.runtimeContext()); } outcome::checked decryptResult(KeySet &keySet, PublicResult &result) { return topLevelDecryptResult((*this), keySet, result); } TypedClientLambda(ClientLambda &lambda) : ClientLambda(lambda) { // TODO: check parameter types // TODO: add static check on types vs lambda inputs/outpus } protected: // Workaround, gcc 6 does not support partial template specialisation in class template friend outcome::checked topLevelDecryptResult(ClientLambda &lambda, KeySet &keySet, PublicResult &result); }; template <> outcome::checked topLevelDecryptResult(ClientLambda &lambda, KeySet &keySet, PublicResult &result); template <> outcome::checked topLevelDecryptResult(ClientLambda &lambda, KeySet &keySet, PublicResult &result); template <> outcome::checked topLevelDecryptResult(ClientLambda &lambda, KeySet &keySet, PublicResult &result); } // namespace clientlib } // namespace concretelang #endif