Files
MP-SPDZ/Math/Setup.cpp

166 lines
3.5 KiB
C++

#include "Math/Setup.h"
#include "Math/gfp.h"
#include "Math/gf2n.h"
#include "Tools/mkpath.h"
#include <fstream>
#include "Math/gfp.hpp"
/*
* Just setup the primes, doesn't need NTL.
* Sets idx and m to be used by SHE setup if necessary
*/
bigint SPDZ_Data_Setup_Primes(int lgp)
{
int idx, m;
bigint p;
SPDZ_Data_Setup_Primes(p, lgp, idx, m);
return p;
}
void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m)
{
#ifdef VERBOSE
cerr << "Setting up parameters" << endl;
#endif
switch (lgp)
{ case -1:
m=16;
idx=1; // Any old figures will do, but need to be for lgp at last
lgp=32; // Switch to bigger prime to get parameters
break;
case 32:
m=8192;
idx=0;
break;
case 64:
m=16384;
idx=1;
break;
case 128:
m=32768;
idx=2;
break;
case 256:
m=32768;
idx=3;
break;
case 512:
m=65536;
idx=4;
break;
default:
m=1;
idx=0;
#ifdef VERBOSE
cerr << "no precomputed parameters, trying anyway" << endl;
#endif
break;
}
#ifdef VERBOSE
cerr << "m = " << m << endl;
#endif
generate_prime(p, lgp, m);
}
bigint generate_prime(int lgp, int m)
{
bigint p;
generate_prime(p, lgp, m);
return p;
}
void generate_prime(bigint& p, int lgp, int m)
{
if (OnlineOptions::singleton.prime > 0)
{
p = OnlineOptions::singleton.prime;
if (!probPrime(p))
{
cerr << p << " is not a prime" << endl;
exit(1);
}
else if (m != 1 and p % m != 1)
{
cerr << p
<< " is not compatible with our encryption scheme, must be 1 modulo "
<< m << endl;
exit(1);
}
else
return;
}
bigint u;
int ex;
ex = lgp - numBits(m);
if (ex < 0)
throw runtime_error(to_string(lgp) + "-bit primes too small "
"for our parameters");
u = 1;
u = (u << ex) * m;
p = u + 1;
while (!probPrime(p) || numBits(p) < lgp)
{
u = u + m;
p = u + 1;
}
#ifdef VERBOSE
cerr << "\t p = " << p << " u = " << u << " : ";
cerr << lgp << " <= " << numBits(p) << endl;
#endif
}
void write_online_setup(string dirname, const bigint& p)
{
if (p == 0)
throw runtime_error("prime cannot be 0");
stringstream ss;
ss << dirname;
cerr << "Writing to file in " << ss.str() << endl;
// create preprocessing dir. if necessary
if (mkdir_p(ss.str().c_str()) == -1)
{
cerr << "mkdir_p(" << ss.str() << ") failed\n";
throw file_error(ss.str());
}
// Output the data
ss << "/Params-Data";
ofstream outf;
outf.open(ss.str().c_str());
outf << p << endl;
if (!outf.good())
throw file_error("cannot write to " + ss.str());
}
void check_setup(string dir, bigint pr)
{
bigint p;
string filename = dir + "Params-Data";
ifstream(filename) >> p;
if (p == 0)
throw runtime_error("no modulus in " + filename);
if (p != pr)
throw runtime_error("wrong modulus in " + filename);
}
string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod,
const string& type_short)
{
string res = prep_dir + "/" + to_string(nparties) + "-" + type_short;
if (log2mod > 1)
res += "-" + to_string(log2mod);
res += "/";
if (mkdir_p(res.c_str()) < 0)
throw file_error(res);
return res;
}