SeComLib
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros Pages
data_packer.hpp
Go to the documentation of this file.
1 /*
2 SeComLib
3 Copyright 2012-2013 TU Delft, Information Security & Privacy Lab (http://isplab.tudelft.nl/)
4 
5 Contributors:
6 Inald Lagendijk (R.L.Lagendijk@TUDelft.nl)
7 Mihai Todor (todormihai@gmail.com)
8 Thijs Veugen (P.J.M.Veugen@tudelft.nl)
9 Zekeriya Erkin (z.erkin@tudelft.nl)
10 
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
14 
15 http://www.apache.org/licenses/LICENSE-2.0
16 
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
30 #ifndef DATA_PACKER_IMPLEMENTATION_GUARD
31 #define DATA_PACKER_IMPLEMENTATION_GUARD
32 
33 namespace SeComLib {
34 namespace Core {
43  template <typename T_CryptoProvider>
44  DataPacker<T_CryptoProvider>::DataPacker (const T_CryptoProvider &cryptoProvider, const size_t dataSize, const size_t frontPaddingSize, const size_t backPaddingSize) :
45  cryptoProvider(cryptoProvider),
46  frontPaddingSize(frontPaddingSize),
47  dataSize(dataSize),
48  backPaddingSize(backPaddingSize) {
49  this->initialize();
50  }
51 
58  template <typename T_CryptoProvider>
61 
62  //initialize the packed buckets
63  BigInteger packedBuckets(0);
64  //initialize the bucket counter
65  size_t packedBucketCounter = 0;
66  for (typename DataPacker<T_CryptoProvider>::UnpackedData::const_iterator bucketIterator = input.begin(); bucketIterator != input.end(); ++bucketIterator) {
67  //test if we packed enough buckets to fill the entire span of the message space
68  if (packedBucketCounter == this->bucketsPerEncryption) {
69  output.emplace_back(this->cryptoProvider.EncryptInteger(packedBuckets));
70 
71  //create the next packed bucket
72  packedBuckets = BigInteger(0);
73  packedBucketCounter = 0;
74  }
75 
77 
78  //pack front padding element
79  if (this->frontPaddingSize > 0) {
80  packedBuckets += (*bucketIterator).frontPadding << (static_cast<unsigned long>(packedBucketCounter * this->bucketSize));
81  }
82 
83  //pack data element
84  packedBuckets += (*bucketIterator).data << (static_cast<unsigned long>(packedBucketCounter * this->bucketSize + this->frontPaddingSize));
85 
86  //pack back padding element
87  if (this->backPaddingSize > 0) {
88  packedBuckets += (*bucketIterator).backPadding << (static_cast<unsigned long>(packedBucketCounter * this->bucketSize + this->frontPaddingSize + this->dataSize));
89  }
90 
91  ++packedBucketCounter;
92  }
93 
94  //don't forget to store the last set of packed buckets (it might not contain as many as this->bucketsPerEncryption buckets, so we need to know how many buckets to unpack)
95  output.emplace_back(this->cryptoProvider.EncryptInteger(packedBuckets));
96 
97  return output;
98  }
99 
107  template <typename T_CryptoProvider>
110 
111  for (typename DataPacker<T_CryptoProvider>::PackedData::const_iterator packedDataIterator = input.begin(); packedDataIterator != input.end(); ++packedDataIterator) {
112  //decrypt the packed buckets
113  BigInteger packedBuckets = this->cryptoProvider.DecryptInteger(*packedDataIterator);
114 
115  //extract each data bucket
116  for (size_t i = 0; i < this->bucketsPerEncryption; ++i) {
117  DataBucket bucket;
118 
119  if (this->frontPaddingSize > 0) {
120  //extract front padding element
121  bucket.frontPadding = packedBuckets % this->frontPaddingMessageSpace;
122 
123  //shift bits to extract the data element
124  packedBuckets >>= static_cast<unsigned long>(this->frontPaddingSize);
125  }
126 
127  //extract the data element
128  bucket.data = packedBuckets % this->dataMessageSpace;
129 
130  if (this->backPaddingSize > 0) {
131  //shift bits to extract the back padding element
132  packedBuckets >>= static_cast<unsigned long>(this->dataSize);
133 
134  //extract back padding element
135  bucket.backPadding = packedBuckets % this->backPaddingMessageSpace;
136 
137  //shift bits to extract the next bucket
138  packedBuckets >>= static_cast<unsigned long>(this->backPaddingSize);
139  }
140 
141  output.emplace_back(bucket);
142 
144  if (output.size() == totalBucketCount) {
145  return output;
146  }
147 
148  //debug
149  /*
150  std::cout << bucket.frontPadding.ToString() << std::endl;
151  std::cout << bucket.data.ToString() << std::endl;
152  std::cout << bucket.backPadding.ToString() << std::endl;
153  std::cout << packedBuckets.ToString() << std::endl;
154  */
155  }
156  }
157 
158  if (output.size() != totalBucketCount) {
160  throw std::runtime_error("Unexpected number of packed buckets.");
161  }
162 
163  return output;
164  }
165 
171  template <typename T_CryptoProvider>
174 
175  for (typename DataPacker<T_CryptoProvider>::PackedData::const_iterator lhsIterator = lhs.begin(), rhsIterator = rhs.begin();
176  lhsIterator != lhs.end(), rhsIterator != rhs.end();
177  ++lhsIterator, ++rhsIterator) {
178  output.emplace_back(*lhsIterator + *rhsIterator);
179  }
180 
181  return output;
182  }
183 
189  template <typename T_CryptoProvider>
192 
193  for (typename DataPacker<T_CryptoProvider>::PackedData::const_iterator lhsIterator = lhs.begin(); lhsIterator != lhs.end(); ++lhsIterator) {
194  output.emplace_back(*lhsIterator * rhs);
195  }
196 
197  return output;
198  }
199 
207  template <typename T_CryptoProvider>
209  this->dataMessageSpace = BigInteger(1) << static_cast<unsigned long>(this->dataSize);
210  this->frontPaddingMessageSpace = BigInteger(1) << static_cast<unsigned long>(this->frontPaddingSize);
211  this->backPaddingMessageSpace = BigInteger(1) << static_cast<unsigned long>(this->backPaddingSize);
212 
213  this->bucketSize = this->frontPaddingSize + this->dataSize + this->backPaddingSize;
214 
215  this->bucketsPerEncryption = this->cryptoProvider.GetMessageSpaceSize() / static_cast<unsigned long>(this->bucketSize);
216  }
217 
218 }//namespace Core
219 }//namespace SeComLib
220 
221 #endif//DATA_PACKER_IMPLEMENTATION_GUARD
BigInteger backPadding
The back padding ( )
Definition: data_packer.h:61
Container for data buckets.
Definition: data_packer.h:52
PackedData Pack(const UnpackedData &input) const
Pack data.
Definition: data_packer.hpp:59
BigInteger data
The data ( )
Definition: data_packer.h:58
UnpackedData Unpack(const PackedData &input, const size_t totalBucketCount) const
Unpack data.
std::deque< typename DataPacker< T_CryptoProvider >::DataBucket > UnpackedData
Define a vector template specialization for vectors of unpacked data.
Definition: data_packer.h:65
void initialize()
Initialize class members.
Template class which implements the data packing functionality.
Definition: data_packer.h:46
BigInteger frontPadding
The front padding ( )
Definition: data_packer.h:55
DataPacker(const T_CryptoProvider &cryptoProvider, const size_t dataSize, const size_t frontPaddingSize=0, const size_t backPaddingSize=0)
Constructor with custom data sizes.
Definition: data_packer.hpp:44
PackedData HomomorphicAdd(const PackedData &lhs, const PackedData &rhs)
Add two vectors of packed data.
std::deque< typename T_CryptoProvider::Ciphertext > PackedData
Define a vector template specialization for vectors of packed data.
Definition: data_packer.h:68
PackedData HomomorphicMultiply(const PackedData &lhs, const BigInteger &rhs)
Multiply a vector of packed data with a constant plaintext term.