aboutsummaryrefslogtreecommitdiff
path: root/epid/common-testhelper/finite_field_wrapper-testhelper.cc
blob: 6240415f172a38cf3287ffac2632cb0192d48307 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*############################################################################
  # Copyright 2016 Intel Corporation
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  ############################################################################*/

/*!
 * \file
 * \brief FiniteField C++ wrapper implementation.
 */
#include "epid/common-testhelper/errors-testhelper.h"
#include "epid/common/math/bignum.h"
#include "epid/common-testhelper/finite_field_wrapper-testhelper.h"
#include "epid/common-testhelper/ffelement_wrapper-testhelper.h"

/// finite field deleter type
struct FiniteFieldDeleter {
  /// finite field deleter
  void operator()(FiniteField* ff) {
    if (ff) {
      DeleteFiniteField(&ff);
    }
  }
};

/// finite field deleter singlton
FiniteFieldDeleter finite_field_deleter;

/// Internal state of the finite field wrapper
struct FiniteFieldObj::State {
  /// Inner state of complex fields
  struct InnerState {
    /// The ground field
    FiniteFieldObj gf_;
    /// The ground element
    FfElementObj ge_;
  };
  /// Inner state
  /*!
  We store a pointer to InnerState so simple fields
  that are not composed from other fields do not result
  in an infinite series of fields.

  Instead simple fields have a NULL inner_state and
  complex fields have it set.
  */
  InnerState* inner_state;

  /// The stored FiniteField
  std::shared_ptr<FiniteField> ff_;

  ///  Maximum size of field element
  size_t size_;

  /// constructor
  State() : ff_(nullptr, finite_field_deleter), size_(0) {
    inner_state = nullptr;
  }

  // State instances are not meant to be copied.
  // Explicitly delete copy constructor and assignment operator.
  State(const State&) = delete;
  State& operator=(const State&) = delete;

  /// destructor
  ~State() {
    if (inner_state) {
      delete inner_state;
      inner_state = nullptr;
    }
  }

  /// setter for inner_state
  void SetInnerState(FiniteFieldObj const& gf, FfElementObj const& ge) {
    if (!inner_state) {
      inner_state = new InnerState;
      inner_state->gf_ = gf;
      inner_state->ge_ = ge;
    }
  }

  /// setter for inner_state
  void SetInnerState(InnerState* state) {
    if (state) {
      if (!inner_state) {
        inner_state = new InnerState;
      }
      if (!inner_state) {
        inner_state->gf_ = state->gf_;
        inner_state->ge_ = state->ge_;
      }
    } else {
      if (inner_state) {
        delete inner_state;
        inner_state = nullptr;
      }
    }
  }
};

FiniteFieldObj::FiniteFieldObj() : state_(new State()) {
  /*
  to avoid a bug in ipp this is one less than the
  actual max value we could take.
  */
  const BigNumStr max_prime = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                               0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFe};
  FiniteField* temp = nullptr;
  NewFiniteField(&max_prime, &temp);
  state_->ff_.reset(temp, finite_field_deleter);
  state_->size_ = sizeof(max_prime);
}

FiniteFieldObj::FiniteFieldObj(FiniteFieldObj const& other)
    : state_(new State) {
  state_->ff_ = other.state_->ff_;
  state_->size_ = other.state_->size_;
  state_->SetInnerState(other.state_->inner_state);
}

FiniteFieldObj& FiniteFieldObj::operator=(FiniteFieldObj const& other) {
  state_->ff_ = other.state_->ff_;
  state_->size_ = other.state_->size_;
  state_->SetInnerState(other.state_->inner_state);
  return *this;
}

FiniteFieldObj::FiniteFieldObj(BigNumStr const& prime) : state_(new State) {
  FiniteField* temp = nullptr;
  NewFiniteField(&prime, &temp);
  state_->ff_.reset(temp, finite_field_deleter);
  state_->size_ = sizeof(prime);
}

FiniteFieldObj::FiniteFieldObj(FiniteFieldObj const& ground_field,
                               FfElementObj const& ground_element, int degree)
    : state_(new State) {
  FiniteField* temp = nullptr;
  state_->SetInnerState(ground_field, ground_element);
  NewFiniteFieldViaBinomalExtension(ground_field, ground_element, degree,
                                    &temp);
  state_->ff_.reset(temp, finite_field_deleter);
  state_->size_ = ground_field.GetElementMaxSize() * degree;
}

FiniteFieldObj::~FiniteFieldObj() {}

FiniteFieldObj::operator FiniteField*() { return state_->ff_.get(); }

FiniteFieldObj::operator const FiniteField*() const {
  return state_->ff_.get();
}

FiniteField* FiniteFieldObj::get() { return state_->ff_.get(); }

FiniteField const* FiniteFieldObj::getc() const { return state_->ff_.get(); }

size_t FiniteFieldObj::GetElementMaxSize() const { return state_->size_; }