1 /*
2  * Copyright 2020 Google LLC.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     https://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef RLWE_CONTEXT_H_
17 #define RLWE_CONTEXT_H_
18 
19 #include <memory>
20 
21 #include "absl/memory/memory.h"
22 #include "error_params.h"
23 #include "ntt_parameters.h"
24 #include "status_macros.h"
25 #include "statusor.h"
26 
27 namespace rlwe {
28 
29 // Defines and holds the context of the RLWE encryption scheme.
30 // Thread safe..
31 template <typename ModularInt>
32 class RlweContext {
33   using Int = typename ModularInt::Int;
34   using ModulusParams = typename ModularInt::Params;
35 
36  public:
37   // Structure to hold parameters for the RLWE encryption scheme. The parameters
38   // include:
39   // - modulus, an Int which needs to be congruent to 1 modulo 2 * (1 << log_n);
40   // - log_n: the logarithm of the number of coefficients of the polynomials;
41   // - log_t: the number of bits of the plaintext space, which will be equal to
42   //          (1 << log_t) + 1;
43   // - variance, the error variance to use when sampling noises or secrets.
44   struct Parameters {
45     Int modulus;
46     size_t log_n;
47     size_t log_t;
48     size_t variance;
49   };
50 
51   // Factory function to create a context from a context_params.
Create(Parameters context_params)52   static rlwe::StatusOr<std::unique_ptr<const RlweContext>> Create(
53       Parameters context_params) {
54     // Create the modulus parameters.
55     RLWE_ASSIGN_OR_RETURN(
56         std::unique_ptr<const ModulusParams> modulus_parameters,
57         ModulusParams::Create(context_params.modulus));
58     // Create the NTT parameters.
59     RLWE_ASSIGN_OR_RETURN(NttParameters<ModularInt> ntt_params_temp,
60                           InitializeNttParameters<ModularInt>(
61                               context_params.log_n, modulus_parameters.get()));
62     std::unique_ptr<const NttParameters<ModularInt>> ntt_params =
63         std::make_unique<const NttParameters<ModularInt>>(
64             std::move(ntt_params_temp));
65     // Create the error parameters.
66     RLWE_ASSIGN_OR_RETURN(ErrorParams<ModularInt> error_params_temp,
67                           ErrorParams<ModularInt>::Create(
68                               context_params.log_t, context_params.variance,
69                               modulus_parameters.get(), ntt_params.get()));
70     std::unique_ptr<const ErrorParams<ModularInt>> error_params =
71         std::make_unique<const ErrorParams<ModularInt>>(
72             std::move(error_params_temp));
73     return absl::WrapUnique<const RlweContext>(
74         new RlweContext(std::move(modulus_parameters), std::move(ntt_params),
75                         std::move(error_params), std::move(context_params)));
76   }
77 
78   // Disallow copy and copy-assign, allow move and move-assign.
79   RlweContext(const RlweContext&) = delete;
80   RlweContext& operator=(const RlweContext&) = delete;
81   RlweContext(RlweContext&&) = default;
82   RlweContext& operator=(RlweContext&&) = default;
83   ~RlweContext() = default;
84 
85   // Getters.
GetModulusParams()86   const ModulusParams* GetModulusParams() const {
87     return modulus_parameters_.get();
88   }
GetNttParams()89   const NttParameters<ModularInt>* GetNttParams() const {
90     return ntt_parameters_.get();
91   }
GetErrorParams()92   const ErrorParams<ModularInt>* GetErrorParams() const {
93     return error_parameters_.get();
94   }
GetModulus()95   const Int GetModulus() const { return context_params_.modulus; }
GetLogN()96   const size_t GetLogN() const { return context_params_.log_n; }
GetN()97   const size_t GetN() const { return 1 << context_params_.log_n; }
GetLogT()98   const size_t GetLogT() const { return context_params_.log_t; }
GetT()99   const Int GetT() const {
100     return (static_cast<Int>(1) << context_params_.log_t) + static_cast<Int>(1);
101   }
GetVariance()102   const size_t GetVariance() const { return context_params_.variance; }
103 
104  private:
RlweContext(std::unique_ptr<const ModulusParams> modulus_parameters,std::unique_ptr<const NttParameters<ModularInt>> ntt_parameters,std::unique_ptr<const ErrorParams<ModularInt>> error_parameters,Parameters context_params)105   RlweContext(std::unique_ptr<const ModulusParams> modulus_parameters,
106               std::unique_ptr<const NttParameters<ModularInt>> ntt_parameters,
107               std::unique_ptr<const ErrorParams<ModularInt>> error_parameters,
108               Parameters context_params)
109       : modulus_parameters_(std::move(modulus_parameters)),
110         ntt_parameters_(std::move(ntt_parameters)),
111         error_parameters_(std::move(error_parameters)),
112         context_params_(std::move(context_params)) {}
113 
114   const std::unique_ptr<const ModulusParams> modulus_parameters_;
115   const std::unique_ptr<const NttParameters<ModularInt>> ntt_parameters_;
116   const std::unique_ptr<const ErrorParams<ModularInt>> error_parameters_;
117   const Parameters context_params_;
118 };
119 
120 }  // namespace rlwe
121 
122 #endif  // RLWE_CONTEXT_H_
123