Automatic prime generation; live preprocessing for replicated secret sharing over rings.

This commit is contained in:
Marcel Keller
2018-12-19 11:39:55 +11:00
parent 875b704ed2
commit 9805501bbc
19 changed files with 118 additions and 61 deletions

View File

@@ -457,5 +457,6 @@ template class Passing_MAC_Check<gf2n_short>;
template class MAC_Check_Base<Rep3Share<gfp>>;
template class MAC_Check_Base<Rep3Share<gf2n>>;
template class MAC_Check_Base<Rep3Share<Integer>>;
template class MAC_Check_Base<MaliciousRep3Share<gfp>>;
template class MAC_Check_Base<MaliciousRep3Share<gf2n>>;

View File

@@ -25,6 +25,8 @@ public:
static int size() { return sizeof(a); }
static string type_string() { return "integer"; }
static void init_default(int lgp) { (void)lgp; }
IntBase() { a = 0; }
IntBase(long a) : a(a) {}

View File

@@ -12,6 +12,14 @@
* 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)
{
cout << "Setting up parameters" << endl;
@@ -137,12 +145,12 @@ void read_setup(const string& dir_prefix)
bigint p;
string filename = dir_prefix + "Params-Data";
cerr << "loading params from: " << filename << endl;
// backwards compatibility hack
if (dir_prefix.compare("") == 0)
filename = string(PREP_DIR "Params-Data");
cerr << "loading params from: " << filename << endl;
ifstream inpf(filename.c_str());
if (inpf.fail()) { throw file_error(filename.c_str()); }
inpf >> p;

View File

@@ -25,6 +25,7 @@ void write_online_setup(ofstream& outf, string dirname, const bigint& p, int lg2
// Setup primes only
// Chooses a p of at least lgp bits
bigint SPDZ_Data_Setup_Primes(int lgp);
void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m);
void generate_prime(bigint& p, int lgp, int m);

View File

@@ -1,10 +1,16 @@
#include "Math/gfp.h"
#include "Math/Setup.h"
#include "Exceptions/Exceptions.h"
Zp_Data gfp::ZpD;
void gfp::init_default(int lgp)
{
init_field(SPDZ_Data_Setup_Primes(lgp));
}
void gfp::almost_randomize(PRNG& G)
{
G.get_octets((octet*)a.x,t()*sizeof(mp_limb_t));

View File

@@ -38,6 +38,8 @@ class gfp
static void init_field(const bigint& p,bool mont=true)
{ ZpD.init(p,mont); }
static void init_default(int lgp);
static bigint pr()
{ return ZpD.pr; }
static int t()

View File

@@ -21,15 +21,6 @@ int main(int argc, const char** argv)
opt.syntax = "./Player-Online.x [OPTIONS] <playernum> <progname>\n";
opt.example = "./Player-Online.x -lgp 64 -lg2 128 -m new 0 sample-prog\n./Player-Online.x -pn 13000 -h localhost 1 sample-prog\n";
opt.add(
"128", // Default.
0, // Required?
1, // Number of args expected.
0, // Delimiter if expecting multiple args.
"Bit length of GF(p) field (default: 128)", // Help description.
"-lgp", // Flag token.
"--lgp" // Flag token.
);
opt.add(
to_string(gf2n::default_degree()).c_str(), // Default.
0, // Required?
@@ -200,12 +191,11 @@ int main(int argc, const char** argv)
}
string memtype, hostname, ipFileName;
int lg2, lgp, pnbase, opening_sum, max_broadcast;
int lg2, pnbase, opening_sum, max_broadcast;
int p2pcommsec;
int my_port;
opt.get("--portnumbase")->getInt(pnbase);
opt.get("--lgp")->getInt(lgp);
opt.get("--lg2")->getInt(lg2);
opt.get("--memory")->getString(memtype);
opt.get("--hostname")->getString(hostname);
@@ -228,7 +218,7 @@ int main(int argc, const char** argv)
vector<public_signing_key> pubkeys;
secret_signing_key mykey;
public_signing_key mypublickey;
string prep_data_prefix = get_prep_dir(2, lgp, lg2);
string prep_data_prefix = get_prep_dir(2, online_opts.lgp, lg2);
Config::read_player_config(prep_data_prefix,mynum,pubkeys,mykey,mypublickey);
keys = new CommsecKeysPackage(pubkeys,mykey,mypublickey);
}
@@ -258,7 +248,7 @@ int main(int argc, const char** argv)
try
#endif
{
Machine<sgfp, Share<gf2n>>(playerno, playerNames, progname, memtype, lgp, lg2,
Machine<sgfp, Share<gf2n>>(playerno, playerNames, progname, memtype, lg2,
opt.get("--direct")->isSet, opening_sum, opt.get("--parallel")->isSet,
opt.get("--threads")->isSet, max_broadcast, false, false,
online_opts).run();

View File

@@ -82,6 +82,17 @@ Preprocessing<Rep3Share<gf2n>>* Preprocessing<Rep3Share<gf2n>>::get_new(
return new Sub_Data_Files<Rep3Share<gf2n>>(machine.get_N(), machine.prep_dir_prefix, usage);
}
template<>
template<>
Preprocessing<Rep3Share<Integer>>* Preprocessing<Rep3Share<Integer>>::get_new(
Machine<Rep3Share<Integer>, Rep3Share<gf2n>>& machine, DataPositions& usage)
{
if (machine.live_prep)
return new ReplicatedRingPrep<Rep3Share<Integer>>;
else
return new Sub_Data_Files<Rep3Share<Integer>>(machine.get_N(), machine.prep_dir_prefix, usage);
}
template<>
template<>
Preprocessing<MaliciousRep3Share<gfp>>* Preprocessing<MaliciousRep3Share<gfp>>::get_new(

View File

@@ -37,7 +37,7 @@ BaseMachine::BaseMachine() : nthreads(0)
template<class sint, class sgf2n>
Machine<sint, sgf2n>::Machine(int my_number, Names& playerNames,
string progname_str, string memtype, int lgp, int lg2, bool direct,
string progname_str, string memtype, int lg2, bool direct,
int opening_sum, bool parallel, bool receive_threads, int max_broadcast,
bool use_encryption, bool live_prep, OnlineOptions opts)
: my_number(my_number), N(playerNames), tn(0), numt(0), usage_unknown(false),
@@ -51,32 +51,42 @@ Machine<sint, sgf2n>::Machine(int my_number, Names& playerNames,
this->max_broadcast = N.num_players();
// Set up the fields
prep_dir_prefix = get_prep_dir(N.num_players(), lgp, lg2);
read_setup(prep_dir_prefix);
prep_dir_prefix = get_prep_dir(N.num_players(), opts.lgp, lg2);
char filename[1024];
int nn;
sprintf(filename, (prep_dir_prefix + "Player-MAC-Keys-P%d").c_str(), my_number);
inpf.open(filename);
if (inpf.fail())
{
cerr << "Could not open MAC key file. Perhaps it needs to be generated?\n";
throw file_error(filename);
}
inpf >> nn;
if (nn!=N.num_players())
{ cerr << "KeyGen was last run with " << nn << " players." << endl;
cerr << " - You are running Online with " << N.num_players() << " players." << endl;
exit(1);
try
{
read_setup(prep_dir_prefix);
int nn;
sprintf(filename, (prep_dir_prefix + "Player-MAC-Keys-P%d").c_str(), my_number);
inpf.open(filename);
if (inpf.fail())
{
cerr << "Could not open MAC key file. Perhaps it needs to be generated?\n";
throw file_error(filename);
}
inpf >> nn;
if (nn!=N.num_players())
{ cerr << "KeyGen was last run with " << nn << " players." << endl;
cerr << " - You are running Online with " << N.num_players() << " players." << endl;
exit(1);
}
alphapi.input(inpf,true);
alpha2i.input(inpf,true);
cerr << "MAC Key p = " << alphapi << endl;
cerr << "MAC Key 2 = " << alpha2i << endl;
inpf.close();
}
catch (file_error& e)
{
cerr << "Field or MAC key setup failed, using defaults"
<< endl;
sint::clear::init_default(opts.lgp);
gf2n::init_field(gf2n::default_degree());
}
alphapi.input(inpf,true);
alpha2i.input(inpf,true);
cerr << "MAC Key p = " << alphapi << endl;
cerr << "MAC Key 2 = " << alpha2i << endl;
inpf.close();
// Initialize the global memory
if (memtype.compare("new")==0)

View File

@@ -72,7 +72,7 @@ class Machine : public BaseMachine
OnlineOptions opts;
Machine(int my_number, Names& playerNames, string progname,
string memtype, int lgp, int lg2, bool direct, int opening_sum, bool parallel,
string memtype, int lg2, bool direct, int opening_sum, bool parallel,
bool receive_threads, int max_broadcast, bool use_encryption, bool live_prep,
OnlineOptions opts);

View File

@@ -8,6 +8,7 @@
OnlineOptions::OnlineOptions()
{
interactive = false;
lgp = 128;
}
OnlineOptions::OnlineOptions(ez::ezOptionParser& opt, int argc,
@@ -22,10 +23,20 @@ OnlineOptions::OnlineOptions(ez::ezOptionParser& opt, int argc,
"-I", // Flag token.
"--interactive" // Flag token.
);
opt.add(
"128", // Default.
0, // Required?
1, // Number of args expected.
0, // Delimiter if expecting multiple args.
"Bit length of GF(p) field (default: 128)", // Help description.
"-lgp", // Flag token.
"--lgp" // Flag token.
);
opt.parse(argc, argv);
interactive = opt.isSet("-I");
opt.get("--lgp")->getInt(lgp);
opt.resetArgs();
}

View File

@@ -12,6 +12,7 @@ class OnlineOptions
{
public:
bool interactive;
int lgp;
OnlineOptions();
OnlineOptions(ez::ezOptionParser& opt, int argc, const char** argv);

View File

@@ -48,7 +48,7 @@ ReplicatedMachine<T, U>::ReplicatedMachine(int argc, const char** argv,
0, // Required?
0, // Number of args expected.
0, // Delimiter if expecting multiple args.
"Preprocessing from files (default for rings).", // Help description.
"Preprocessing from files", // Help description.
"-F", // Flag token.
"--file-preprocessing" // Flag token.
);
@@ -91,7 +91,7 @@ ReplicatedMachine<T, U>::ReplicatedMachine(int argc, const char** argv,
Names N;
Server* server = Server::start_networking(N, playerno, 3, hostname, pnb);
Machine<T, U>(playerno, N, progname, "empty", 128,
Machine<T, U>(playerno, N, progname, "empty",
gf2n::default_degree(), 0, 0, 0, 0, 0, use_encryption,
live_prep, online_opts).run();

View File

@@ -9,12 +9,12 @@
#include "Auth/ReplicatedMC.h"
template<class T>
ReplicatedPrep<T>::ReplicatedPrep() : protocol(0)
ReplicatedRingPrep<T>::ReplicatedRingPrep() : protocol(0)
{
}
template<class T>
void ReplicatedPrep<T>::buffer_triples()
void ReplicatedRingPrep<T>::buffer_triples()
{
assert(protocol != 0);
auto& triples = this->triples;
@@ -48,7 +48,7 @@ void BufferPrep<T>::get_three(Dtype dtype, T& a, T& b, T& c)
}
template<class T>
void ReplicatedPrep<T>::buffer_squares()
void ReplicatedRingPrep<T>::buffer_squares()
{
assert(protocol != 0);
auto& squares = this->squares;
@@ -68,6 +68,7 @@ void ReplicatedPrep<T>::buffer_squares()
template<class T>
void ReplicatedPrep<T>::buffer_inverses()
{
auto protocol = this->protocol;
assert(protocol != 0);
ReplicatedMC<T> MC;
BufferPrep<T>::buffer_inverses(MC, protocol->P);
@@ -124,8 +125,8 @@ void BufferPrep<T>::get_two(Dtype dtype, T& a, T& b)
}
}
template<>
void ReplicatedPrep<Rep3Share<gfp>>::buffer_bits()
template<class T>
void ReplicatedRingPrep<T>::buffer_bits()
{
assert(protocol != 0);
#ifdef BIT_BY_SQUARE
@@ -146,7 +147,9 @@ void ReplicatedPrep<Rep3Share<gfp>>::buffer_bits()
if (bits.empty())
throw runtime_error("squares were all zero");
#else
vector<vector<Rep3Share<gfp>>> player_bits(3, vector<Rep3Share<gfp>>(buffer_size));
auto buffer_size = this->buffer_size;
auto& bits = this->bits;
vector<vector<T>> player_bits(3, vector<T>(buffer_size));
vector<octetStream> os(2);
SeededPRNG G;
for (auto& share : player_bits[protocol->P.my_num()])
@@ -165,8 +168,8 @@ void ReplicatedPrep<Rep3Share<gfp>>::buffer_bits()
for (int i = 0; i < buffer_size; i++)
prot.prepare_mul(player_bits[0][i], player_bits[1][i]);
prot.exchange();
vector<Rep3Share<gfp>> first_xor(buffer_size);
gfp two(2);
vector<T> first_xor(buffer_size);
typename T::clear two(2);
for (int i = 0; i < buffer_size; i++)
first_xor[i] = player_bits[0][i] + player_bits[1][i] - prot.finalize_mul() * two;
prot.init_mul();
@@ -180,7 +183,7 @@ void ReplicatedPrep<Rep3Share<gfp>>::buffer_bits()
}
template<>
void ReplicatedPrep<Rep3Share<gf2n>>::buffer_bits()
void ReplicatedRingPrep<Rep3Share<gf2n>>::buffer_bits()
{
assert(protocol != 0);
for (int i = 0; i < DIV_CEIL(buffer_size, gf2n::degree()); i++)
@@ -228,3 +231,6 @@ template class BufferPrep<MaliciousRep3Share<gfp>>;
template class BufferPrep<MaliciousRep3Share<gf2n>>;
template class ReplicatedPrep<Rep3Share<gfp>>;
template class ReplicatedPrep<Rep3Share<gf2n>>;
template class ReplicatedRingPrep<Rep3Share<Integer>>;
template class ReplicatedRingPrep<Rep3Share<gfp>>;
template class ReplicatedRingPrep<Rep3Share<gf2n>>;

View File

@@ -41,21 +41,28 @@ public:
};
template<class T>
class ReplicatedPrep : public BufferPrep<T>
class ReplicatedRingPrep : public BufferPrep<T>
{
protected:
template<class U> friend class MaliciousRepPrep;
Replicated<T>* protocol;
void buffer_triples();
void buffer_squares();
void buffer_inverses();
void buffer_inverses() { throw runtime_error("not inverses in rings"); }
void buffer_bits();
public:
ReplicatedPrep();
ReplicatedRingPrep();
void set_protocol(Replicated<T>& protocol) { this->protocol = &protocol; }
};
template<class T>
class ReplicatedPrep: public ReplicatedRingPrep<T>
{
void buffer_inverses();
};
#endif /* PROCESSOR_REPLICATEDPREP_H_ */

View File

@@ -110,7 +110,7 @@ compute the preprocessing time for a particulor computation.
1) Edit `CONFIG` or `CONFIG.mine` to your needs:
- To benchmark malicious SPDZ, some honest-majority three-party computation (semi-honest modulo 2^64 or malicious binary), or BMR, add the following line at the top: `MY_CFLAGS = -DINSECURE`
- To benchmark malicious SPDZ or BMR, add the following line at the top: `MY_CFLAGS = -DINSECURE`
- `PREP_DIR` should point to should be a local, unversioned directory to store preprocessing data (default is `Player-Data` in the current directory).
- For the SPDZ-2 and Overdrive offline phases, set `USE_NTL = 1` and `MOD = -DMAX_MOD_SZ=6`.
- To use GF(2^40), in particular for the SPDZ-2 offline phase, set `USE_GF2N_LONG = 0`. This will deactive anything that requires GF(2^128) such as MASCOT.
@@ -244,11 +244,9 @@ Compile the necessary programs:
`make -j 8 rep-ring`
Run setup to create necessary files and random bits (needed for comparisons etc.):
Run setup to generate SSL keys and certificates. See the section replicated secret sharing for binary circuits below for details.
`Scripts/setup-online.sh 3`
This will also generate SSL keys and certificates. See the section replicated secret sharing for binary circuits below for details.
`Scripts/setup-ssl.sh`
In order to compile a program, use `./compile.py -R 64`, for example:

View File

@@ -7,4 +7,4 @@ export PLAYERS=3
. $HERE/run-common.sh
run_player replicated-field-party.x ${1:-test_all} || exit 1
run_player replicated-field-party.x ${1:-test_all} -lgp ${2:-128} || exit 1

View File

@@ -3,6 +3,9 @@
HERE=$(cd `dirname $0`; pwd)
SPDZROOT=$HERE/..
# prime field bit length
bits=${1:-128}
$HERE/setup-ssl.sh 3
$SPDZROOT/Setup.x 3 128 0 online
$SPDZROOT/Setup.x 3 ${bits} 0 online