1 /*############################################################################
2   # Copyright 2016-2018 Intel Corporation
3   #
4   # Licensed under the Apache License, Version 2.0 (the "License");
5   # you may not use this file except in compliance with the License.
6   # You may obtain a copy of the License at
7   #
8   #     http://www.apache.org/licenses/LICENSE-2.0
9   #
10   # Unless required by applicable law or agreed to in writing, software
11   # distributed under the License is distributed on an "AS IS" BASIS,
12   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   # See the License for the specific language governing permissions and
14   # limitations under the License.
15   ############################################################################*/
16 
17 /*!
18  * \file
19  * \brief FiniteField C++ wrapper implementation.
20  */
21 #include "epid/common-testhelper/finite_field_wrapper-testhelper.h"
22 #include "epid/common-testhelper/errors-testhelper.h"
23 #include "epid/common-testhelper/ffelement_wrapper-testhelper.h"
24 #include "epid/common/math/bignum.h"
25 
26 /// finite field deleter type
27 struct FiniteFieldDeleter {
28   /// finite field deleter
operator ()FiniteFieldDeleter29   void operator()(FiniteField* ff) {
30     if (ff) {
31       DeleteFiniteField(&ff);
32     }
33   }
34 };
35 
36 /// finite field deleter singlton
37 FiniteFieldDeleter finite_field_deleter;
38 
39 /// Internal state of the finite field wrapper
40 struct FiniteFieldObj::State {
41   /// Inner state of complex fields
42   struct InnerState {
43     /// The ground field
44     FiniteFieldObj gf_;
45   };
46   /// Inner state
47   /*!
48   We store a pointer to InnerState so simple fields
49   that are not composed from other fields do not result
50   in an infinite series of fields.
51 
52   Instead simple fields have a NULL inner_state and
53   complex fields have it set.
54   */
55   InnerState* inner_state;
56 
57   /// The stored FiniteField
58   std::shared_ptr<FiniteField> ff_;
59 
60   ///  Maximum size of field element
61   size_t size_;
62 
63   /// constructor
StateFiniteFieldObj::State64   State() : ff_(nullptr, finite_field_deleter), size_(0) {
65     inner_state = nullptr;
66   }
67 
68   // State instances are not meant to be copied.
69   // Explicitly delete copy constructor and assignment operator.
70   State(const State&) = delete;
71   State& operator=(const State&) = delete;
72 
73   /// destructor
~StateFiniteFieldObj::State74   ~State() {
75     if (inner_state) {
76       delete inner_state;
77       inner_state = nullptr;
78     }
79   }
80 
81   /// setter for inner_state
SetInnerStateFiniteFieldObj::State82   void SetInnerState(FiniteFieldObj const& gf) {
83     if (!inner_state) {
84       inner_state = new InnerState;
85       inner_state->gf_ = gf;
86     }
87   }
88 
89   /// setter for inner_state
SetInnerStateFiniteFieldObj::State90   void SetInnerState(InnerState* state) {
91     if (state) {
92       if (!inner_state) {
93         inner_state = new InnerState;
94       }
95       if (!inner_state) {
96         inner_state->gf_ = state->gf_;
97       }
98     } else {
99       if (inner_state) {
100         delete inner_state;
101         inner_state = nullptr;
102       }
103     }
104   }
105 };
106 
FiniteFieldObj()107 FiniteFieldObj::FiniteFieldObj() : state_(new State()) {
108   const BigNumStr max_prime = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
110                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111                                0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x43};
112   FiniteField* temp = nullptr;
113   NewFiniteField(&max_prime, &temp);
114   state_->ff_.reset(temp, finite_field_deleter);
115   state_->size_ = sizeof(max_prime);
116 }
117 
FiniteFieldObj(FiniteFieldObj const & other)118 FiniteFieldObj::FiniteFieldObj(FiniteFieldObj const& other)
119     : state_(new State) {
120   state_->ff_ = other.state_->ff_;
121   state_->size_ = other.state_->size_;
122   state_->SetInnerState(other.state_->inner_state);
123 }
124 
operator =(FiniteFieldObj const & other)125 FiniteFieldObj& FiniteFieldObj::operator=(FiniteFieldObj const& other) {
126   state_->ff_ = other.state_->ff_;
127   state_->size_ = other.state_->size_;
128   state_->SetInnerState(other.state_->inner_state);
129   return *this;
130 }
131 
FiniteFieldObj(BigNumStr const & prime)132 FiniteFieldObj::FiniteFieldObj(BigNumStr const& prime) : state_(new State) {
133   FiniteField* temp = nullptr;
134   NewFiniteField(&prime, &temp);
135   state_->ff_.reset(temp, finite_field_deleter);
136   state_->size_ = sizeof(prime);
137 }
138 
FiniteFieldObj(FiniteFieldObj const & ground_field,FfElementObj const & ground_element,int degree)139 FiniteFieldObj::FiniteFieldObj(FiniteFieldObj const& ground_field,
140                                FfElementObj const& ground_element, int degree)
141     : state_(new State) {
142   FiniteField* temp = nullptr;
143   state_->SetInnerState(ground_field);
144   NewFiniteFieldViaBinomalExtension(ground_field, ground_element, degree,
145                                     &temp);
146   state_->ff_.reset(temp, finite_field_deleter);
147   state_->size_ = ground_field.GetElementMaxSize() * degree;
148 }
149 
FiniteFieldObj(FiniteFieldObj const & ground_field,BigNumStr const * irr_polynomial,int degree)150 FiniteFieldObj::FiniteFieldObj(FiniteFieldObj const& ground_field,
151                                BigNumStr const* irr_polynomial, int degree)
152     : state_(new State) {
153   FiniteField* temp = nullptr;
154   state_->SetInnerState(ground_field);
155   NewFiniteFieldViaPolynomialExtension(ground_field, irr_polynomial, degree,
156                                        &temp);
157   state_->ff_.reset(temp, finite_field_deleter);
158   state_->size_ = ground_field.GetElementMaxSize() * degree;
159 }
160 
~FiniteFieldObj()161 FiniteFieldObj::~FiniteFieldObj() {}
162 
operator FiniteField*()163 FiniteFieldObj::operator FiniteField*() { return state_->ff_.get(); }
164 
operator const FiniteField*() const165 FiniteFieldObj::operator const FiniteField*() const {
166   return state_->ff_.get();
167 }
168 
get()169 FiniteField* FiniteFieldObj::get() { return state_->ff_.get(); }
170 
getc() const171 FiniteField const* FiniteFieldObj::getc() const { return state_->ff_.get(); }
172 
GetElementMaxSize() const173 size_t FiniteFieldObj::GetElementMaxSize() const { return state_->size_; }
174