#inctf2021
#include <vector>
#include <string>
#include <random>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "utils.cpp"
#define HIGH 9
#define LOW 0
using namespace std;
//################################################################################################
int level2()
{
int MAT_SIZE = 5;
vector<int64_t> p;
vector<int64_t> msgvector;
vector<vector<int64_t>> m1(MAT_SIZE, vector<int64_t>(MAT_SIZE));
vector<int> row = {0, 1, 2, 3, 4};
random_device rd;
mt19937 g(rd());
shuffle(row.begin(), row.end(), g);
cout << " =============================\n";
cout << " --------LEVEL2--------\n";
cout << " =============================\n";
for (int x = 0; x < MAT_SIZE; x++)
{
for (int y = 0; y < MAT_SIZE; y++)
{
if ((x == row[0]) || (x == row[1]))
m1[x][y] = 0;
else
m1[x][y] = Genrand(LOW, HIGH);
}
}
long int userInp;
msgvector = m1[row[2]];
FheEncrypt(msgvector);
EncryptedOperations();
p = FheDecrypt();
p = vector<int64_t>(p.begin(), p.begin() + MAT_SIZE + 1);
userInp = VecToNum(p);
msgvector = m1[row[3]];
FheEncrypt(msgvector);
EncryptedOperations();
vector<int64_t> p1;
p = FheDecrypt();
m1[row[1]] = p1 = vector<int64_t>(p.begin(), p.begin() + MAT_SIZE);
msgvector = m1[row[4]];
FheEncrypt(msgvector);
EncryptedOperations();
vector<int64_t> p2;
p = FheDecrypt();
m1[row[0]] = p2 = vector<int64_t>(p.begin(), p.begin() + MAT_SIZE);
vector<int> numVec;
for (int i = 0; i < 5; i++)
if (i == row[1])
{
numVec.push_back(VecToNum(p1));
}
else if (i == row[0])
{
numVec.push_back(VecToNum(p2));
}
else
numVec.push_back(VecToNum(m1[i]));
long int sum = accumulate(numVec.begin(), numVec.end(), 0);
if (sum == userInp)
{
cout << "\n\nYou have mastered encrypted operatoins!!\n";
cout << "Here's the flag: " << printFlag();
}
else
{
cout << "That was close, great going, But no flag for you!!\n\n";
exit(0);
}
return 0;
}
//################################################################################################
//################################################################################################
long int calc_determinant(long int a, long int x)
{
long int res = a * ((pow(a, 2) - (a * x * (-1)))) - -1 * ((pow(a, 2) * x) - (pow(x, 2) * a * (-1))) + 0 * ((pow(a * x, 2)) - (pow(a, 2) * pow(x, 2)));
return res;
}
//-------------------------------------------------------------------------------------------------
void gen_hint(long int a, long int x)
{
long int hint;
char opt;
vector<int64_t> v = {a, x};
FheEncrypt(v);
EncryptedOperations();
v = FheDecrypt();
cout << "\nchoose(+,-,*,/): ";
cin >> opt;
if (opt == '+')
hint = v[0] + v[1];
else if (opt == '*')
hint = v[0] * v[1];
else if (opt == '-')
hint = v[0] - v[1];
else if (opt == '/')
hint = v[0] / v[1];
else
{
cout << "\n\nERROR!! "
<< "Unrecognized Operation!!";
exit(0);
}
cout << "\n\nHere you go: " << hint * (a * x) << "\n";
}
//################################################################################################
//################################################################################################
int level1()
{
int SIZE = 20;
int val = Genrand(1, 500);
int idx;
long int num;
long int sum1 = 0;
long int sum2 = 0;
long int a = Genrand(1, 20);
long int x = Genrand(1, 20);
vector<vector<int>> m(SIZE, vector<int>(SIZE));
vector<vector<int>> v(169, vector<int>(9));
vector<int> mat;
vector<int64_t> msgvector;
cout << " =============================\n";
cout << " --------LEVEL1--------\n";
cout << " =============================\n";
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
m[x][y] = ++val;
}
}
int d = m.size();
int r = 3;
int c = 3;
for (int i = 0; i < d - r + 1; i++)
{
for (int j = 0; j < d - c + 1; j++)
{
for (int p = 0; p < r; p++)
{
for (int q = 0; q < c; q++)
{
mat.push_back(m[i + p][j + q]);
}
}
}
}
for (int j = 0; j < int(mat.size()); j += 9)
{
v.push_back(slice(mat, j, j + 9));
}
idx = Genrand(0, v.size() - 1);
vector<int64_t> temp1(begin(v[idx]), end(v[idx]));
vector<int64_t> mvector = temp1;
sum1 = accumulate(mvector.begin(), mvector.end(), 0);
FheEncrypt(mvector);
EncryptedOperations();
vector<int64_t> p = FheDecrypt();
if (sum1 == 0)
{
cout << "\n\nCHALLENGE CORRUPTED!!!!";
exit(0);
}
if (p[0] == sum1)
cout << "\n\nYou got all the encrypted operations right! Great!!\n\nNow on to the next\n\n";
else
exit(0);
v = {};
mat = {};
r = 5;
c = 4;
for (int i = 0; i < d - r + 1; i++)
{
for (int j = 0; j < d - c + 1; j++)
{
for (int p = 0; p < r; p++)
{
for (int q = 0; q < c; q++)
{
mat.push_back(m[i + p][j + q]);
}
}
}
}
for (int j = 0; j < int(mat.size()); j += 20)
{
v.push_back(slice(mat, j, j + 20));
}
idx = Genrand(0, v.size() - 1);
vector<int64_t> temp2(begin(v[idx]), end(v[idx]));
vector<int64_t> mvector2 = temp2;
sum2 = accumulate(mvector2.begin(), mvector2.end(), 0);
num = mvector2[0];
long int res = calc_determinant(a, 2 * x) - calc_determinant(a, x);
gen_hint(a, x);
cout << "This might make it easier: " << res * num << "\n\n";
FheEncrypt(mvector2);
EncryptedOperations();
p = FheDecrypt();
if (sum2 == 0)
{
cout << "\n\nCHALLENGE CORRUPTED!!!!";
exit(0);
}
if (p[0] == sum2)
cout << "Seems like you got a hang of this!!\nCongrats on completing the first level.\nGo get the flag!\n\n";
else
exit(0);
return 0;
}
//#########################################################################################
//###################################### MAIN() ###########################################
int main()
{
cout << " _______________________________________\n";
cout << "\n WELCOME TO 'ENCRYPTED OPERATIONS SERVER'\n";
cout << " _______________________________________\n\n";
cout << "\nThe server provides you with a set of operations to perform on encrypted data\n";
cout << "All operations are performed on vector(long int) type data.\nThe server parses a string to convert it into vector\n";
cout << "\n\nEx of vector input ->\n```Enter the operand vector: 12 13 14 15```\nThis will be parsed into `vector<int64_t>`\n\nLoading the service......\n\n";
atexit(sayonara);
int ret = level1();
ret = level2();
if (ret == 0)
atexit(arigato);
return 0;
}
//###############################------------------------------#############################
//##############################------------END-----------------############################
#include <vector>
#include <string>
#include <random>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include "homomorphic_system.cpp" // c++ pallisade library is used to implement FHE
homomorphic_system r1;
/*
If u want to check out pallisade library and test out is functionalities the following documentation specifies the build procedure :
https://gitlab.com/palisade/palisade-release#build-instructions ( for installing pallisade locally )
pls be aware that installation can take a while and and on PC's with lower specs might slow down PC performance drastically/crash during installation
PLS NOTE: pallisade installation is NOT NECESSARY in any way for solving this challenge!
*/
CryptoContext<DCRTPoly> cryptoContext = r1.genCC(); // Generates the cryptocontext
LPKeyPair<DCRTPoly> keyPair = r1.genKeys(cryptoContext); // Generates the private key
//################################################################################################
int VecToNum(vector<int64_t> vec)
{
std::vector<int> values(begin(vec), end(vec));
int res = std::accumulate(values.begin(), values.end(), 0, [](int acc, int val)
{ return 10 * acc + val; });
return res;
}
//################################################################################################
int Genrand(int lr, int hr)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distr(lr, hr);
int rnum = distr(gen);
return rnum;
}
//################################################################################################
vector<int> slice(const vector<int> &v, int start = 0, int end = -1)
{
int olen = v.size();
int nlen;
if (end == -1 or end >= olen)
{
nlen = olen - start;
}
else
{
nlen = end - start;
}
vector<int> nv(nlen);
for (int i = 0; i < nlen; i++)
{
nv[i] = v[start + i];
}
return nv;
}
//################################################################################################
/* operations list:
- '+' adds operand vector to encrypted vector
- '*' multiplies operand vector to encrypted vector
- '<' shifts the elements of encrypted vector to left by value specified in 'samt'
- '>' shifts elements of encrypted vector to right by value specified in 'samt'
*/
/* eg operation:
if the following vector -> {1,1,1,1} is encrypted
and operand vector is given as {-2,-2,-2,-2}
operations is '+'
shift amount can be any value in specified range ( since not used )
resultant vector after decrypting will be {-1,-1,-1,-1}
if above operation was '<'
samt = 1
resultant vector after decrypting will be {1,1,1,0}
while shifting operand vector can be given as 0 i.e {0} as it is not used
*/
void EncryptedOperations()
{
char choice = 'y';
char operation; // '+','*','<',">"
int samt; // shift amount
int cnt = 0;
std::cout << "\n\nThe plaintext has been encrypted.\n\n"
<< std::flush;
;
while (choice == 'y' && cnt < 4)
{
std::cout << "\nEnter the operand vector: " << std::flush;
std::string s;
std::getline(std::cin >> std::ws, s);
std::stringstream iss(s);
int number;
std::vector<int64_t> operandVector;
while (iss >> number)
operandVector.push_back(number);
assert(1 <= operandVector.size() && operandVector.size() <= 20);
std::cout << "\nSpecify Operation: ";
std::cin >> operation;
std::cout << "\nEnter shift amount: ";
std::cin >> samt;
assert(1 <= samt && samt < 20);
r1.compute(cryptoContext, operation, samt, operandVector); // performs the operation specified on encrypted vector/ on encrypted and operand vector
std::cout << "\nperform another operation(y/n): ";
std::cin >> choice;
assert(choice == 'y' || choice == 'n');
cnt += 1;
};
std::cout << "\n";
}
//################################################################################################
// msg vector is encrypted using fhe
void FheEncrypt(vector<int64_t> msgvector)
{
r1.genCiphertexts(msgvector, keyPair, cryptoContext);
}
//################################################################################################
// resultant vector after performing the operations is decrypted
vector<int64_t> FheDecrypt()
{
std::vector<int64_t> dt;
dt = r1.decrypt(keyPair, cryptoContext);
return dt;
}
//################################################################################################
std::string printFlag()
{
std::fstream flagfile;
flagfile.open("flag.txt", std::ios::in);
std::string flag;
if (flagfile.is_open())
{
std::string l;
while (getline(flagfile, l))
{
flag += l;
}
flagfile.close();
}
return flag;
}
//################################################################################################
void sayonara(void)
{
std::cout << "\n\n\nExiting!!";
}
//################################################################################################
void arigato(void)
{
std::cout << "\n\n\n"
<< "Thankyou for using the service! Sucessfully performed all operatoions!!";
}
//#############################--------------------------------#####################################
//#############################--------------END---------------#####################################