// 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_ENCRYPTED_ARGS_H #define CONCRETELANG_CLIENTLIB_ENCRYPTED_ARGS_H #include #include "boost/outcome.h" #include "../Common/Error.h" #include "concretelang/ClientLib/ClientParameters.h" #include "concretelang/ClientLib/KeySet.h" #include "concretelang/ClientLib/Types.h" #include "concretelang/Common/BitsSize.h" namespace concretelang { namespace clientlib { using concretelang::error::StringError; class PublicArguments; class EncryptedArgs { /// Temporary object used to hold and encrypt parameters before calling a /// ClientLambda. Use preferably TypeClientLambda and serializeCall(Args...). /// Otherwise convert it to a PublicArguments and use /// serializeCall(PublicArguments, KeySet). public: // Create EncryptedArgument that use the given KeySet to perform // encryption/decryption operations. template static outcome::checked, StringError> create(std::shared_ptr keySet, Args... args) { auto arguments = std::make_shared(); OUTCOME_TRYV(arguments->pushArgs(keySet, args...)); return arguments; } /** Low level interface */ public: // Add a scalar argument. outcome::checked pushArg(uint8_t arg, std::shared_ptr keySet); // Add a vector-tensor argument. outcome::checked pushArg(std::vector arg, std::shared_ptr keySet); template outcome::checked pushArg(std::array arg, std::shared_ptr keySet) { return pushArg(8, (void *)arg.data(), {size}, keySet); } // Add a matrix-tensor argument. template outcome::checked pushArg(std::array, size0> arg, std::shared_ptr keySet) { return pushArg(8, (void *)arg.data(), {size0, size1}, keySet); } // Add a rank3 tensor. template outcome::checked pushArg(std::array, size1>, size0> arg, std::shared_ptr keySet) { return pushArg(8, (void *)arg.data(), {size0, size1, size2}, keySet); } // Generalize by computing shape by template recursion // Set a argument at the given pos as a 1D tensor of T. template outcome::checked pushArg(T *data, size_t dim1, std::shared_ptr keySet) { return pushArg(data, llvm::ArrayRef(&dim1, 1), keySet); } // Set a argument at the given pos as a tensor of T. template outcome::checked pushArg(T *data, llvm::ArrayRef shape, std::shared_ptr keySet) { return pushArg(8 * sizeof(T), static_cast(data), shape, keySet); } outcome::checked pushArg(size_t width, void *data, llvm::ArrayRef shape, std::shared_ptr keySet); template outcome::checked pushArgs(std::shared_ptr keySet, Arg0 arg0, OtherArgs... others) { OUTCOME_TRYV(pushArg(arg0, keySet)); return pushArgs(keySet, others...); } outcome::checked pushArgs(std::shared_ptr keySet) { return checkAllArgs(keySet); } outcome::checked asPublicArguments(ClientParameters clientParameters, RuntimeContext runtimeContext); EncryptedArgs(); ~EncryptedArgs(); private: outcome::checked checkPushTooManyArgs(std::shared_ptr keySetPtr); outcome::checked checkAllArgs(std::shared_ptr keySet); // Add a scalar argument. outcome::checked pushArg(uint64_t arg, std::shared_ptr keySet); // Position of the next pushed argument size_t currentPos; std::vector preparedArgs; // Store buffers of ciphertexts std::vector ciphertextBuffers; }; } // namespace clientlib } // namespace concretelang #endif