/* Copyright (C) 2014 Carlos Aguilar Melchor, Joris Barrier, Marc-Olivier Killijian
* This file is part of XPIR.
*
* XPIR is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* XPIR is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XPIR. If not, see .
*/
#include "PIRReplyExtraction_internal.hpp"
#include "apps/client/PIRViewCLI.hpp"
//#define DEBUG
/**
* Class constructor.
* Params :
* - crypto_ptr crypto : HomomorphicCrypto shared_ptr ;
* - PIRParameters& param : PIRParameters reference ;
* - signal1 : writeEvent listeners reference shared with PIRClient ;
* - ignal1 : messageEvent listeners reference shared with PIRClient.
**/
PIRReplyExtraction_internal::PIRReplyExtraction_internal(PIRParameters& param_, HomomorphicCrypto& cryptoMethod_) :
filePath("reception"),
pirParams(param_),
cryptoMethod(cryptoMethod_),
repliesBuffer("coucou"),
fileSize(0)
{}
/**
* Parallely extract/decrypt file, store clear chunk in clearChunks shared queue.
**/
void PIRReplyExtraction_internal::extractReply(int aggregated_maxFileSize, shared_queue* clearChunks)
{
unsigned long ciphertext_nbr = 1;
unsigned int data_size, data_size2b;
char *data, *in_data, *in_data_2b;
double start = omp_get_wtime();
uint64_t total_ciphertext_nbr= 0;
for (unsigned int rec_lvl = pirParams.d ; rec_lvl >= 1 ; rec_lvl--)
{
ciphertext_nbr = ceil(static_cast(aggregated_maxFileSize) / static_cast(cryptoMethod.getPublicParameters().getAbsorptionBitsize(0)/GlobalConstant::kBitsPerByte));
#ifdef DEBUG
std::cout<<"PIRReplyExtraction_internal: First layer ciphertext_nbr="< 1) {
memcpy(in_data_2b+(data_size2b * j), out_data, data_size2b);
free(out_data);
}
else
{
clearChunks->push(out_data);
#ifdef CRYPTO_DEBUG
cout << "PIRReplyExtraction_internal : pushed " << hex;
for (int k = 0 ; k < data_size2b ; k++)
cout << (unsigned short) *(out_data+k) << " ";
cout << dec << endl;
#endif
}
if(rec_lvl == pirParams.d) free(data);
}
if (rec_lvl < pirParams.d) free(in_data);
in_data = in_data_2b;
}
cout << "PIRReplyExtraction_internal: Reply extraction finished, " << total_ciphertext_nbr <<
" reply elements decrypted in " << omp_get_wtime() - start << " seconds" << endl;
}
/**
* Start extractReply in a thread.
**/
void PIRReplyExtraction_internal::startExtractReply(int aggregated_maxFileSize, shared_queue* clearChunks)
{
replyThread = boost::thread(&PIRReplyExtraction_internal::extractReply, this, aggregated_maxFileSize, clearChunks);
}
void PIRReplyExtraction_internal::setFileParam(string filename_ ,int fileSize_)
{
assert (!filename_.empty());
assert (fileSize_ >= 0);
fileSize = fileSize_;
filename = filename_;
}
PIRReplyExtraction_internal::~PIRReplyExtraction_internal()
{
joinThread();
while (!repliesBuffer.empty())
free(repliesBuffer.pop_front());
}
/**
* Join reply extraction thread if it's possible.
**/
void PIRReplyExtraction_internal::joinThread()
{
if (replyThread.joinable()) replyThread.join();
}
int PIRReplyExtraction_internal::getChosenFileSize()
{
return fileSize;
}
//#pragma omp parallel for private(thread_index, buf) shared(index, index_prod)
// for (unsigned int i = 0 ; i < paquet_nbr ; i++)
// {
//#pragma omp critical
// {
// buf = repliesBuffer.pop_front();
// thread_index = index++;
// }
//
// char *tmp1;
// size_t ciph_size = 0, clear_size;
// unsigned int exp_factor = pirParams.recLvl;
//
// if (start == 0)
//#pragma omp critical
// start = omp_get_wtime();
//
// for (unsigned int i = 0 ; i < pirParams.d; i++)
// {
// ciph_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i);
// clear_size = cryptoMethod.getPublicParameters().getCiphBitsizeFromRecLvl(pirParams.recLvl - i -1);
// tmp1 = buf;
//
// if (exp_factor - i == 1)
// clear_size--;
//
// buf = cryptoMethod.decrypt(tmp1, exp_factor - i, ciph_size, clear_size);
//
// delete[] tmp1;
// }
//
// while (thread_index != index_prod)
// usleep(5);
//
//#pragma omp critical
// {
// clearChunks.push(buf);
// index_prod = thread_index + 1;
// }
// }
//printf("\n:: Déchiffrement -> Temp écoulé : %f seconds\n", omp_get_wtime() - start);