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