mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-07 20:53:55 -05:00
CowGear, more protocols with replicated secret sharing.
This commit is contained in:
@@ -30,7 +30,7 @@ CommonParty::CommonParty() :
|
||||
#endif
|
||||
cpu_timer.start();
|
||||
timer.start();
|
||||
gf2n::init_field(128);
|
||||
gf2n_long::init_field(128);
|
||||
mac_key.randomize(prng);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ using namespace std;
|
||||
#include "proto_utils.h"
|
||||
#include "network/Node.h"
|
||||
#include "Tools/random.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Tools/time-func.h"
|
||||
#include "GC/Program.h"
|
||||
#include "Tools/FlexBuffer.h"
|
||||
@@ -67,7 +66,7 @@ protected:
|
||||
Timer timers[2];
|
||||
Timer timer;
|
||||
|
||||
gf2n mac_key;
|
||||
gf2n_long mac_key;
|
||||
|
||||
LocalBuffer wires;
|
||||
ReceivedMsgStore wire_storage;
|
||||
@@ -103,7 +102,7 @@ public:
|
||||
gate_id_t next_gate(int skip) { return gate_counter2 += skip; }
|
||||
size_t get_garbled_tbl_size() { return garbled_tbl_size; }
|
||||
|
||||
gf2n get_mac_key() { return mac_key; }
|
||||
gf2n_long get_mac_key() { return mac_key; }
|
||||
};
|
||||
|
||||
class CommonFakeParty : virtual public CommonParty, public NodeUpdatable
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "CommonParty.hpp"
|
||||
#include "ProgramParty.hpp"
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "BMR/Register.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
#ifdef __PURE_SHE__
|
||||
#include "mpirxx.h"
|
||||
@@ -825,6 +826,11 @@ void FakeProgramParty::_compute_prfs_outputs(Key* keys)
|
||||
first_phase(program, prf_processor, prf_machine);
|
||||
}
|
||||
|
||||
void FakeProgramParty::_check_evaluate()
|
||||
{
|
||||
FakeProgramPartySuper::_check_evaluate();
|
||||
}
|
||||
|
||||
void ProgramParty::reset()
|
||||
{
|
||||
CommonParty::reset();
|
||||
@@ -898,11 +904,11 @@ void FakeProgramParty::receive_spdz_wires(ReceivedMsg& msg)
|
||||
#endif
|
||||
if (op == SPDZ_MAC)
|
||||
{
|
||||
gf2n spdz_mac_key;
|
||||
gf2n_long spdz_mac_key;
|
||||
spdz_mac_key.unpack(spdz_wires[op].back());
|
||||
if (!MC)
|
||||
{
|
||||
MC = new Passing_MAC_Check<gf2n>(spdz_mac_key, N, 0);
|
||||
MC = new Passing_MAC_Check<gf2n_long>(spdz_mac_key, N, 0);
|
||||
cout << "MAC key: " << hex << spdz_mac_key << endl;
|
||||
mac_key = spdz_mac_key;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ class FakeProgramParty : virtual public BaseParty, virtual public FakeProgramPar
|
||||
|
||||
void store_garbled_circuit(ReceivedMsg& msg) { ProgramParty::store_garbled_circuit(msg); }
|
||||
|
||||
void _check_evaluate() { FakeProgramPartySuper::_check_evaluate(); }
|
||||
void _check_evaluate();
|
||||
|
||||
void receive_keys(Register& reg);
|
||||
void receive_all_keys(Register& reg, bool external);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "RealGarbleWire.h"
|
||||
#include "RealProgramParty.h"
|
||||
#include "Processor/MascotPrep.h"
|
||||
#include "Protocols/MascotPrep.h"
|
||||
|
||||
template<class T>
|
||||
void RealGarbleWire<T>::garble(PRFOutputs& prf_output,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
template<class T>
|
||||
RealProgramParty<T>* RealProgramParty<T>::singleton = 0;
|
||||
@@ -34,7 +35,7 @@ RealProgramParty<T>::RealProgramParty(int argc, const char** argv) :
|
||||
|
||||
ez::ezOptionParser opt;
|
||||
opt.add(
|
||||
T::needs_ot ? "2" : "3", // Default.
|
||||
T::dishonest_majority ? "2" : "3", // Default.
|
||||
0, // Required?
|
||||
1, // Number of args expected.
|
||||
0, // Delimiter if expecting multiple args.
|
||||
@@ -48,7 +49,11 @@ RealProgramParty<T>::RealProgramParty(int argc, const char** argv) :
|
||||
this->check(nparties);
|
||||
|
||||
NetworkOptions network_opts(opt, argc, argv);
|
||||
OnlineOptions online_opts(opt, argc, argv);
|
||||
OnlineOptions& online_opts = OnlineOptions::singleton;
|
||||
if (T::needs_ot)
|
||||
online_opts = {opt, argc, argv, 1000};
|
||||
else
|
||||
online_opts = {opt, argc, argv};
|
||||
assert(not online_opts.interactive);
|
||||
|
||||
online_opts.finalize(opt, argc, argv);
|
||||
@@ -66,7 +71,7 @@ RealProgramParty<T>::RealProgramParty(int argc, const char** argv) :
|
||||
this->_id = online_opts.playerno + 1;
|
||||
Server* server = Server::start_networking(N, online_opts.playerno, nparties,
|
||||
network_opts.hostname, network_opts.portnum_base);
|
||||
if (T::needs_ot)
|
||||
if (T::dishonest_majority)
|
||||
P = new PlainPlayer(N, 0);
|
||||
else
|
||||
P = new CryptoPlayer(N, 0);
|
||||
@@ -232,5 +237,5 @@ void RealProgramParty<T>::push_spdz_wire(SpdzOp op, const RealGarbleWire<T>& wir
|
||||
for (int i = 0; i < 2; i++)
|
||||
spdz_wire.my_keys[i] = wire.keys[i][this->N.my_num()];
|
||||
spdz_wire.pack(this->spdz_wires[op].back());
|
||||
this->spdz_storage += sizeof(SpdzWire);
|
||||
this->spdz_storage += sizeof(spdz_wire);
|
||||
}
|
||||
|
||||
@@ -914,12 +914,6 @@ void GarbleRegister::load(vector<GC::ReadAccess< GC::Secret<GarbleRegister> > >&
|
||||
TrustedProgramParty::s().load_wire(reg);
|
||||
}
|
||||
|
||||
void KeyVector::operator=(const KeyVector& other)
|
||||
{
|
||||
resize(other.size());
|
||||
avx_memcpy(data(), other.data(), byte_size());
|
||||
}
|
||||
|
||||
KeyVector KeyVector::operator^(const KeyVector& other) const
|
||||
{
|
||||
if (size() != other.size())
|
||||
|
||||
@@ -65,6 +65,7 @@ class KeyVector : public BaseKeyVector
|
||||
{
|
||||
public:
|
||||
KeyVector(int size = 0) : BaseKeyVector(size) {}
|
||||
KeyVector(const KeyVector& other) : BaseKeyVector() { *this = other; }
|
||||
size_t byte_size() const { return size() * sizeof(Key); }
|
||||
void operator=(const KeyVector& source);
|
||||
KeyVector operator^(const KeyVector& other) const;
|
||||
@@ -390,6 +391,12 @@ inline Register::Register(int n_parties) :
|
||||
{
|
||||
}
|
||||
|
||||
inline void KeyVector::operator=(const KeyVector& other)
|
||||
{
|
||||
resize(other.size());
|
||||
avx_memcpy(data(), other.data(), byte_size());
|
||||
}
|
||||
|
||||
inline void KeyVector::unserialize(ReceivedMsg& source, int n_parties)
|
||||
{
|
||||
resize(n_parties);
|
||||
|
||||
@@ -63,7 +63,7 @@ void EvalRegister::store(GC::Memory<U>& mem,
|
||||
check_for_doubles(accesses, "storing");
|
||||
auto& party = ProgramPartySpec<U>::s();
|
||||
vector<U> S, S2, S3, S4, S5, SS;
|
||||
vector<gf2n> exts;
|
||||
vector<gf2n_long> exts;
|
||||
int n_registers = 0;
|
||||
for (auto access : accesses)
|
||||
n_registers += access.source.get_regs().size();
|
||||
@@ -78,11 +78,11 @@ void EvalRegister::store(GC::Memory<U>& mem,
|
||||
party.get_spdz_wire(SPDZ_STORE, spdz_wire);
|
||||
const EvalRegister& reg = sources[i];
|
||||
U tmp;
|
||||
gf2n ext = (int)reg.get_external();
|
||||
gf2n_long ext = (int)reg.get_external();
|
||||
//cout << "ext:" << ext << "/" << (int)reg.get_external() << " " << endl;
|
||||
tmp.add(spdz_wire.mask, ext, (int)party.get_id() - 1, party.get_mac_key());
|
||||
S.push_back(tmp);
|
||||
tmp *= gf2n(1) << i;
|
||||
tmp *= gf2n_long(1) << i;
|
||||
dest += tmp;
|
||||
const Key& key = reg.external_key(party.get_id());
|
||||
Key& expected_key = spdz_wire.my_keys[(int)reg.get_external()];
|
||||
@@ -193,7 +193,7 @@ void EvalRegister::load(vector<GC::ReadAccess<T> >& accesses,
|
||||
party.MC->Check(*party.P);
|
||||
#endif
|
||||
|
||||
vector<gf2n> masked;
|
||||
vector<gf2n_long> masked;
|
||||
party.MC->POpen_Begin(masked, shares, *party.P);
|
||||
party.MC->POpen_End(masked, shares, *party.P);
|
||||
vector<octetStream> keys(party.get_n_parties());
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef BMR_SPDZWIRE_H_
|
||||
#define BMR_SPDZWIRE_H_
|
||||
|
||||
#include "Math/Share.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Key.h"
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
#include "proto_utils.h"
|
||||
#include "msg_types.h"
|
||||
#include "SpdzWire.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include "Register_inline.h"
|
||||
|
||||
#include "CommonParty.hpp"
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "BMR/Register.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
TrustedProgramParty* TrustedProgramParty::singleton = 0;
|
||||
|
||||
@@ -421,7 +422,7 @@ void TrustedProgramParty::garble()
|
||||
NoMemory dynamic_memory;
|
||||
second_phase(program, processor, machine, dynamic_memory);
|
||||
|
||||
vector< Share<gf2n> > tmp;
|
||||
vector< Share<gf2n_long> > tmp;
|
||||
make_share(tmp, 1, get_n_parties(), mac_key, prng);
|
||||
for (int i = 0; i < get_n_parties(); i++)
|
||||
tmp[i].get_mac().pack(spdz_wires[SPDZ_MAC][i]);
|
||||
@@ -444,7 +445,8 @@ void TrustedProgramParty::garble()
|
||||
|
||||
void TrustedProgramParty::store_spdz_wire(SpdzOp op, const Register& reg)
|
||||
{
|
||||
make_share(mask_shares, gf2n(reg.get_mask()), get_n_parties(), gf2n(get_mac_key()), prng);
|
||||
make_share(mask_shares, gf2n_long(reg.get_mask()), get_n_parties(),
|
||||
gf2n_long(get_mac_key()), prng);
|
||||
for (int i = 0; i < get_n_parties(); i++)
|
||||
{
|
||||
SpdzWire wire;
|
||||
|
||||
@@ -121,7 +121,7 @@ private:
|
||||
#endif
|
||||
|
||||
vector<octetStream> spdz_wires[SPDZ_OP_N];
|
||||
vector< Share<gf2n> > mask_shares;
|
||||
vector< Share<gf2n_long> > mask_shares;
|
||||
|
||||
Timer random_timer;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ void Node::Broadcast2(SendBuffer& msg) {
|
||||
|
||||
void Node::_identify() {
|
||||
char* msg = id_msg;
|
||||
strncpy(msg, ID_HDR, strlen(ID_HDR));
|
||||
memcpy(msg, ID_HDR, strlen(ID_HDR));
|
||||
memcpy(msg+strlen(ID_HDR), (const char *)&_id, sizeof(_id));
|
||||
//printf("Node:: identifying myself:\n");
|
||||
SendBuffer buffer;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
The changelog explains changes pulled through from the private development repository. Bug fixes and small enchancements are committed between releases and not documented here.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- CowGear protocol (LowGear with covert security)
|
||||
- Protocols that sacrifice after than before
|
||||
- More protocols for replicated secret sharing over rings
|
||||
- Fixed security bug: Some protocols with supposed malicious security wouldn't check players' inputs when generating random bits.
|
||||
|
||||
## 0.0.9 (Apr 30, 2019)
|
||||
|
||||
- Complete BMR for all GF(2^n) protocols
|
||||
|
||||
11
CONFIG
11
CONFIG
@@ -17,13 +17,14 @@ USE_NTL = 0
|
||||
USE_GF2N_LONG = 1
|
||||
|
||||
# set to -march=<architecture> for optimization
|
||||
# SSE4.2 is required homomorphic encryption in GF(2^n) when compiling with clang
|
||||
# AES-NI is required for BMR
|
||||
# PCLMUL is required for GF(2^128) computation
|
||||
# AVX2 support (Haswell or later) is used to optimize OT
|
||||
# AVX/AVX2 is required for replicated binary secret sharing
|
||||
# BMI2 is used to optimize multiplication modulo a prime
|
||||
# ADX is used to optimize big integer additions
|
||||
ARCH = -mtune=native -msse4.1 -maes -mpclmul -mavx -mavx2 -mbmi2 -madx
|
||||
ARCH = -mtune=native -msse4.1 -msse4.2 -maes -mpclmul -mavx -mavx2 -mbmi2 -madx
|
||||
|
||||
# allow to set compiler in CONFIG.mine
|
||||
CXX = g++
|
||||
@@ -35,9 +36,11 @@ ifeq ($(USE_GF2N_LONG),1)
|
||||
GF2N_LONG = -DUSE_GF2N_LONG
|
||||
endif
|
||||
|
||||
# MAX_MOD_SZ must be at least ceil(len(p)/len(word))
|
||||
# Default is 2, which suffices for 128-bit p
|
||||
# MOD = -DMAX_MOD_SZ=2
|
||||
# MAX_MOD_SZ (for FHE) must be least and GFP_MOD_SZ (for computation)
|
||||
# must be exactly ceil(len(p)/len(word)) for the relevant prime p
|
||||
# Default for GFP_MOD_SZ is 2, which is good for 128-bit p
|
||||
# Default for MAX_MOD_SZ is 10, which suffices for all Overdrive protocols
|
||||
# MOD = -DMAX_MOD_SZ=10 -DGFP_MOD_SZ=2
|
||||
|
||||
LDLIBS = -lmpirxx -lmpir -lsodium $(MY_LDLIBS)
|
||||
LDLIBS += -lboost_system -lssl -lcrypto
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
|
||||
#include "Math/Z2k.h"
|
||||
#include "Math/Share.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Math/Spdz2kShare.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
#include "Math/gf2n.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/Share.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "Tools/ezOptionParser.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "GC/MaliciousRepSecret.h"
|
||||
@@ -15,8 +15,9 @@
|
||||
#include "Math/Setup.h"
|
||||
#include "Processor/Data_Files.h"
|
||||
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
@@ -309,7 +310,7 @@ int main(int argc, const char** argv)
|
||||
cout << "--------------\n";
|
||||
cout << "Final Keys :\t p: " << keyp << "\n\t\t 2: " << key2 << endl;
|
||||
|
||||
check<sgfp>(keyp, N);
|
||||
check<Share<gfp>>(keyp, N);
|
||||
check<Share<gf2n>>(key2, N);
|
||||
|
||||
if (N == 3)
|
||||
|
||||
@@ -75,7 +75,7 @@ class StraightlineAllocator:
|
||||
# unused register
|
||||
self.alloc_reg(j, alloc_pool)
|
||||
unused_regs.append(j)
|
||||
if unused_regs and len(unused_regs) == len(i.get_def()):
|
||||
if unused_regs and len(unused_regs) == len(list(i.get_def())):
|
||||
# only report if all assigned registers are unused
|
||||
print "Register(s) %s never used, assigned by '%s' in %s" % \
|
||||
(unused_regs,i,format_trace(i.caller))
|
||||
@@ -252,7 +252,7 @@ class Merger:
|
||||
if len(merge) >= self.max_parallel_open:
|
||||
do_merge(merge)
|
||||
merge[:] = []
|
||||
for merge in merges.itervalues():
|
||||
for merge in reversed(sorted(merges.itervalues())):
|
||||
if merge:
|
||||
do_merge(merge)
|
||||
self.input_nodes = remaining_input_nodes
|
||||
@@ -481,7 +481,7 @@ class Merger:
|
||||
# find first depth that has the right type and isn't full
|
||||
skipped_depths = set()
|
||||
while (depth in round_type and \
|
||||
round_type[depth] != type(instr)) or \
|
||||
round_type[depth] != instr.merge_id()) or \
|
||||
(int(options.max_parallel_open) > 0 and \
|
||||
parallel_open[depth] >= int(options.max_parallel_open)):
|
||||
skipped_depths.add(depth)
|
||||
@@ -490,7 +490,7 @@ class Merger:
|
||||
for d in skipped_depths:
|
||||
next_available_depth[type(instr), d] = depth
|
||||
|
||||
round_type[depth] = type(instr)
|
||||
round_type[depth] = instr.merge_id()
|
||||
parallel_open[depth] += len(instr.args) * instr.get_size()
|
||||
depths[n] = depth
|
||||
|
||||
@@ -567,7 +567,7 @@ class Merger:
|
||||
open_count = 0
|
||||
for i,inst in zip(xrange(len(instructions) - 1, -1, -1), reversed(instructions)):
|
||||
# remove if instruction has result that isn't used
|
||||
unused_result = not G.degree(i) and len(inst.get_def()) \
|
||||
unused_result = not G.degree(i) and len(list(inst.get_def())) \
|
||||
and reduce(operator.and_, (reg.can_eliminate for reg in inst.get_def())) \
|
||||
and not isinstance(inst, (DoNotEliminateInstruction))
|
||||
stop_node = G.get_attr(i, 'stop')
|
||||
|
||||
@@ -1357,6 +1357,10 @@ class muls(base.VarArgsInstruction, base.DataInstruction):
|
||||
def get_repeat(self):
|
||||
return len(self.args) / 3
|
||||
|
||||
def merge_id(self):
|
||||
# can merge different sizes
|
||||
return type(self)
|
||||
|
||||
# def expand(self):
|
||||
# s = [program.curr_block.new_reg('s') for i in range(9)]
|
||||
# c = [program.curr_block.new_reg('c') for i in range(3)]
|
||||
@@ -1397,6 +1401,7 @@ class mulrs(base.VarArgsInstruction, base.DataInstruction):
|
||||
for arg in self.args[2::4] + self.args[3::4]), [])
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class dotprods(base.VarArgsInstruction, base.DataInstruction):
|
||||
""" Secret dot product. """
|
||||
__slots__ = []
|
||||
@@ -1429,7 +1434,7 @@ class dotprods(base.VarArgsInstruction, base.DataInstruction):
|
||||
i += self.args[i]
|
||||
|
||||
def get_repeat(self):
|
||||
return sum(self.args[i] / 2 for i in self.bases())
|
||||
return sum(self.args[i] / 2 for i in self.bases()) * self.get_size()
|
||||
|
||||
def get_def(self):
|
||||
return [self.args[i + 1] for i in self.bases()]
|
||||
|
||||
@@ -176,6 +176,7 @@ opcodes = dict(
|
||||
|
||||
def int_to_bytes(x):
|
||||
""" 32 bit int to big-endian 4 byte conversion. """
|
||||
assert(x < 2**32 and x >= -2**32)
|
||||
return [(x >> 8*i) % 256 for i in (3,2,1,0)]
|
||||
|
||||
|
||||
@@ -545,12 +546,12 @@ class Instruction(object):
|
||||
|
||||
def get_used(self):
|
||||
""" Return the set of registers that are read in this instruction. """
|
||||
return set(arg for arg,w in zip(self.args, self.arg_format) if \
|
||||
return (arg for arg,w in zip(self.args, self.arg_format) if \
|
||||
format_str_is_reg(w) and not format_str_is_writeable(w))
|
||||
|
||||
def get_def(self):
|
||||
""" Return the set of registers that are written to in this instruction. """
|
||||
return set(arg for arg,w in zip(self.args, self.arg_format) if \
|
||||
return (arg for arg,w in zip(self.args, self.arg_format) if \
|
||||
format_str_is_writeable(w))
|
||||
|
||||
def get_pre_arg(self):
|
||||
@@ -575,6 +576,9 @@ class Instruction(object):
|
||||
def add_usage(self, req_node):
|
||||
pass
|
||||
|
||||
def merge_id(self):
|
||||
return type(self), self.get_size()
|
||||
|
||||
# String version of instruction attempting to replicate encoded version
|
||||
def __str__(self):
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ class Function:
|
||||
self.function = function
|
||||
self.name = name
|
||||
if name is None:
|
||||
self.name = self.function.__name__ + '-' + str(id(function))
|
||||
self.name = self.function.__name__
|
||||
self.compile_args = compile_args
|
||||
def __call__(self, *args):
|
||||
args = tuple(arg.read() if isinstance(arg, MemValue) else arg for arg in args)
|
||||
@@ -286,10 +286,10 @@ class Function:
|
||||
def wrapped_function(*compile_args):
|
||||
base = get_arg()
|
||||
bases = dict((t, regint.load_mem(base + i)) \
|
||||
for i,t in enumerate(type_args))
|
||||
for i,t in enumerate(sorted(type_args)))
|
||||
runtime_args = [None] * len(args)
|
||||
for t,i_args in type_args.iteritems():
|
||||
for i,i_arg in enumerate(i_args):
|
||||
for t in sorted(type_args):
|
||||
for i,i_arg in enumerate(type_args[t]):
|
||||
runtime_args[i_arg] = t.load_mem(bases[t] + i)
|
||||
return self.function(*(list(compile_args) + runtime_args))
|
||||
self.on_first_call(wrapped_function)
|
||||
@@ -298,7 +298,7 @@ class Function:
|
||||
base = instructions.program.malloc(len(type_args), 'ci')
|
||||
bases = dict((t, get_program().malloc(len(type_args[t]), t)) \
|
||||
for t in type_args)
|
||||
for i,reg_type in enumerate(type_args):
|
||||
for i,reg_type in enumerate(sorted(type_args)):
|
||||
store_in_mem(bases[reg_type], base + i)
|
||||
for j,i_arg in enumerate(type_args[reg_type]):
|
||||
if get_reg_type(args[i_arg]) != reg_type:
|
||||
@@ -393,8 +393,7 @@ def method_block(function):
|
||||
if self in compiled_functions:
|
||||
return compiled_functions[self](*args)
|
||||
else:
|
||||
name = '%s-%s-%d' % (type(self).__name__, function.__name__, \
|
||||
id(self))
|
||||
name = '%s-%s' % (type(self).__name__, function.__name__)
|
||||
block = FunctionBlock(function, name=name, compile_args=(self,))
|
||||
compiled_functions[self] = block
|
||||
return block(*args)
|
||||
@@ -475,7 +474,7 @@ def chunky_odd_even_merge_sort(a):
|
||||
a[m], a[m+step] = cond_swap(a[m], a[m+step])
|
||||
for i in range(len(a)):
|
||||
a[i].store_in_mem(i * a[i].sizeof())
|
||||
chunk = MPCThread(round, 'sort-%d-%d-%03x' % (l,k,random.randrange(256**3)))
|
||||
chunk = MPCThread(round, 'sort-%d-%d' % (l,k))
|
||||
chunk.start()
|
||||
chunk.join()
|
||||
#round()
|
||||
@@ -511,8 +510,7 @@ def chunkier_odd_even_merge_sort(a, n=None, max_chunk_size=512, n_threads=7, use
|
||||
load_secret_mem(base + 1))
|
||||
store_in_mem(x, base)
|
||||
store_in_mem(y, base + 1)
|
||||
chunks[size] = FunctionTape(swap_list, 'sort-%d-%03x' %
|
||||
(size, random.randrange(256**3)))
|
||||
chunks[size] = FunctionTape(swap_list, 'sort-%d' % size)
|
||||
return chunks[size](base)
|
||||
|
||||
def run_round(size):
|
||||
@@ -563,9 +561,9 @@ def chunkier_odd_even_merge_sort(a, n=None, max_chunk_size=512, n_threads=7, use
|
||||
postproc_chunks.append((mem_op, (a_addr, step, tmp_addr)))
|
||||
else:
|
||||
if k not in wrap_chunks:
|
||||
pre_chunk = FunctionTape(mem_op, 'pre-%d-%03x' % (k,random.randrange(256**3)),
|
||||
pre_chunk = FunctionTape(mem_op, 'pre-%d' % k,
|
||||
compile_args=[True])
|
||||
post_chunk = FunctionTape(mem_op, 'post-%d-%03x' % (k,random.randrange(256**3)),
|
||||
post_chunk = FunctionTape(mem_op, 'post-%d' % k,
|
||||
compile_args=[False])
|
||||
wrap_chunks[k] = (pre_chunk, post_chunk)
|
||||
pre_chunk, post_chunk = wrap_chunks[k]
|
||||
@@ -649,8 +647,7 @@ def loopy_chunkier_odd_even_merge_sort(a, n=None, max_chunk_size=512, n_threads=
|
||||
load_secret_mem(base + 1))
|
||||
store_in_mem(x, base)
|
||||
store_in_mem(y, base + 1)
|
||||
chunks[size] = FunctionTape(swap_list, 'sort-%d-%03x' %
|
||||
(size, random.randrange(256**3)))
|
||||
chunks[size] = FunctionTape(swap_list, 'sort-%d' % size)
|
||||
return chunks[size](base)
|
||||
|
||||
def run_round(size):
|
||||
|
||||
@@ -134,6 +134,9 @@ def random_perm(n):
|
||||
|
||||
WARNING: randomness fixed at compile-time, this is NOT secure
|
||||
"""
|
||||
if not Program.prog.options.insecure:
|
||||
raise CompilerError('no secure implementation of Waksman permution, '
|
||||
'use --insecure to activate')
|
||||
a = range(n)
|
||||
for i in range(n-1, 0, -1):
|
||||
j = randint(0, i)
|
||||
|
||||
@@ -54,7 +54,7 @@ class Program(object):
|
||||
self.galois_length = int(options.galois)
|
||||
print 'Galois length:', self.galois_length
|
||||
self.schedule = [('start', [])]
|
||||
self.main_ctr = 0
|
||||
self.tape_counter = 0
|
||||
self.tapes = []
|
||||
self._curr_tape = None
|
||||
self.EMULATE = True # defaults
|
||||
@@ -77,7 +77,7 @@ class Program(object):
|
||||
Compiler.instructions.mulrs_class, \
|
||||
Compiler.instructions.gmulrs, \
|
||||
Compiler.instructions.dotprods_class, \
|
||||
Compiler.instructions.gdotprods, \
|
||||
Compiler.instructions.gdotprods_class, \
|
||||
Compiler.instructions.asm_input_class, \
|
||||
Compiler.instructions.gasm_input_class]
|
||||
import Compiler.GC.instructions as gc
|
||||
@@ -131,7 +131,9 @@ class Program(object):
|
||||
if progname.endswith('.mpc'):
|
||||
progname = progname[:-4]
|
||||
|
||||
if assemblymode:
|
||||
if os.path.exists(args[0]):
|
||||
self.infile = args[0]
|
||||
elif assemblymode:
|
||||
self.infile = self.programs_dir + '/Source/' + progname + '.asm'
|
||||
else:
|
||||
self.infile = self.programs_dir + '/Source/' + progname + '.mpc'
|
||||
@@ -154,7 +156,6 @@ class Program(object):
|
||||
# make sure there is a current tape
|
||||
self.curr_tape
|
||||
tape_index = len(self.tapes)
|
||||
name += "-%d" % tape_index
|
||||
self.tape_stack.append(self.curr_tape)
|
||||
self.curr_tape = Tape(name, self)
|
||||
self.curr_tape.prevent_direct_memory_write = True
|
||||
@@ -323,10 +324,8 @@ class Program(object):
|
||||
# wait for main thread to finish
|
||||
self.schedule_wait(self._curr_tape)
|
||||
self.main_thread_running = False
|
||||
name = '%s-%d' % (self.name, self.main_ctr)
|
||||
self._curr_tape = Tape(name, self)
|
||||
self._curr_tape = Tape(self.name, self)
|
||||
self.tapes.append(self._curr_tape)
|
||||
self.main_ctr += 1
|
||||
# add to schedule
|
||||
self.schedule_start(self._curr_tape)
|
||||
self.main_thread_running = True
|
||||
@@ -405,11 +404,17 @@ class Program(object):
|
||||
def optimize_for_gc(self):
|
||||
pass
|
||||
|
||||
def get_tape_counter(self):
|
||||
res = self.tape_counter
|
||||
self.tape_counter += 1
|
||||
return res
|
||||
|
||||
class Tape:
|
||||
""" A tape contains a list of basic blocks, onto which instructions are added. """
|
||||
def __init__(self, name, program):
|
||||
""" Set prime p and the initial instructions and registers. """
|
||||
self.program = program
|
||||
name += '-%d' % program.get_tape_counter()
|
||||
self.init_names(name)
|
||||
self.init_registers()
|
||||
self.req_tree = self.ReqNode(name)
|
||||
@@ -627,7 +632,8 @@ class Tape:
|
||||
print 'Re-allocating...'
|
||||
allocator = al.StraightlineAllocator(REG_MAX)
|
||||
def alloc_loop(block):
|
||||
for reg in block.used_from_scope:
|
||||
for reg in sorted(block.used_from_scope,
|
||||
key=lambda x: (x.reg_type, x.i)):
|
||||
allocator.alloc_reg(reg, block.alloc_pool)
|
||||
for child in block.children:
|
||||
if child.instructions:
|
||||
@@ -647,7 +653,7 @@ class Tape:
|
||||
print 'Compile offline data requirements...'
|
||||
self.req_num = self.req_tree.aggregate()
|
||||
print 'Tape requires', self.req_num
|
||||
for req,num in self.req_num.items():
|
||||
for req,num in sorted(self.req_num.items()):
|
||||
if num == float('inf'):
|
||||
num = -1
|
||||
if req[1] in data_types:
|
||||
|
||||
@@ -956,8 +956,11 @@ class _secret(_register):
|
||||
@classmethod
|
||||
@set_instruction_type
|
||||
def dot_product(cls, x, y):
|
||||
x = list(x)
|
||||
set_global_vector_size(x[0].size)
|
||||
res = cls()
|
||||
dotprods(res, x, y)
|
||||
reset_global_vector_size()
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
@@ -2183,7 +2186,8 @@ class _single(_number, _structure):
|
||||
|
||||
@classmethod
|
||||
def dot_product(cls, x, y, res_params=None):
|
||||
dp = cls.int_type.dot_product([xx.v for xx in x], [yy.v for yy in y])
|
||||
dp = cls.int_type.dot_product([xx.pre_mul() for xx in x],
|
||||
[yy.pre_mul() for yy in y])
|
||||
return x[0].unreduced(dp, y[0], res_params, len(x)).reduce_after_mul()
|
||||
|
||||
@classmethod
|
||||
@@ -2337,6 +2341,9 @@ class _fix(_single):
|
||||
def load_int(self, v):
|
||||
self.v = self.int_type(v) << self.f
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self._new(self.v[index])
|
||||
|
||||
@vectorize
|
||||
def add(self, other):
|
||||
other = self.coerce(other)
|
||||
@@ -2579,7 +2586,7 @@ class squant_params(object):
|
||||
self.S = float(S)
|
||||
except:
|
||||
self.S = S
|
||||
self.Z = Z
|
||||
self.Z = MemValue.if_necessary(Z)
|
||||
self.k = k
|
||||
self._store = {}
|
||||
if program.options.ring:
|
||||
@@ -2627,6 +2634,7 @@ class squant_params(object):
|
||||
size = unreduced.v.size
|
||||
n_shift = util.expand(n_shift, size)
|
||||
shifted_Z = util.expand(shifted_Z, size)
|
||||
int_mult = util.expand(int_mult, size)
|
||||
tmp = unreduced.v * int_mult + shifted_Z
|
||||
shifted = tmp.round(self.max_length, n_shift,
|
||||
squant.kappa, squant.round_nearest)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "Networking/sockets.h"
|
||||
#include "Tools/int.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include <sodium.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "Networking/STS.h"
|
||||
#include "Tools/int.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include <sodium.h>
|
||||
#include <iostream>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Ciphertext.h"
|
||||
#include "PPData.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
|
||||
Ciphertext::Ciphertext(const FHE_PK& pk) : Ciphertext(pk.get_params())
|
||||
|
||||
@@ -71,6 +71,11 @@ class Ciphertext
|
||||
template<class FD>
|
||||
void mul(const Ciphertext& c, const Plaintext_<FD>& a) { ::mul(*this, c, a); }
|
||||
|
||||
template<class FD>
|
||||
Ciphertext operator+(const Plaintext_<FD>& other) { Ciphertext res = *this; res += other; return res; }
|
||||
template<class FD>
|
||||
Ciphertext& operator+=(const Plaintext_<FD>& other) { cc0 += other.get_poly(); return *this; }
|
||||
|
||||
bool operator==(const Ciphertext& c) { return pk_id == c.pk_id && cc0.equals(c.cc0) && cc1.equals(c.cc1); }
|
||||
bool operator!=(const Ciphertext& c) { return !(*this == c); }
|
||||
|
||||
|
||||
@@ -168,6 +168,14 @@ istream& operator>>(istream& s,FFT_Data& FFTD)
|
||||
}
|
||||
|
||||
|
||||
void FFT_Data::hash(octetStream& o) const
|
||||
{
|
||||
octetStream tmp;
|
||||
pack(tmp);
|
||||
o.concat(tmp.hash());
|
||||
}
|
||||
|
||||
|
||||
void FFT_Data::pack(octetStream& o) const
|
||||
{
|
||||
R.pack(o);
|
||||
|
||||
@@ -41,6 +41,7 @@ class FFT_Data
|
||||
|
||||
void init_field() const { gfp::init_field(prData.pr); }
|
||||
|
||||
void hash(octetStream& o) const;
|
||||
void pack(octetStream& o) const;
|
||||
void unpack(octetStream& o);
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
#include "FHE_Keys.h"
|
||||
#include "Ciphertext.h"
|
||||
#include "P2Data.h"
|
||||
#include "PPData.h"
|
||||
#include "FFT_Data.h"
|
||||
#include "FHEOffline/FullSetup.h"
|
||||
|
||||
|
||||
@@ -52,8 +55,10 @@ void FHE_PK::KeyGen(Rq_Element& sk, PRNG& G, int noise_boost)
|
||||
mul(e0,e0,PK.pr);
|
||||
add(PK.b0,PK.b0,e0);
|
||||
|
||||
#ifdef CHECK_NOISE
|
||||
// strict check not working for GF(2^n)
|
||||
PK.check_noise(PK.b0 - PK.a0 * sk, false);
|
||||
#endif
|
||||
|
||||
if (params->n_mults() > 0)
|
||||
{
|
||||
@@ -88,7 +93,7 @@ void FHE_PK::check_noise(const FHE_SK& SK)
|
||||
|
||||
void FHE_PK::check_noise(const Rq_Element& x, bool check_modulo)
|
||||
{
|
||||
|
||||
assert(pr != 0);
|
||||
vector<bigint> noise = x.to_vec_bigint();
|
||||
bigint m = 0;
|
||||
if (check_modulo)
|
||||
@@ -104,10 +109,11 @@ void FHE_PK::check_noise(const Rq_Element& x, bool check_modulo)
|
||||
noise[i] /= pr;
|
||||
m = m > noise[i] ? m : noise[i];
|
||||
}
|
||||
cout << "max noise: " << m << endl;
|
||||
cerr << "max noise: " << m << endl;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_PK::encrypt(Ciphertext& c,
|
||||
const Plaintext<gfp,FFT_Data,bigint>& mess,const Random_Coins& rc) const
|
||||
{
|
||||
@@ -123,6 +129,7 @@ void FHE_PK::encrypt(Ciphertext& c,
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_PK::encrypt(Ciphertext& c,
|
||||
const Plaintext<gfp,PPData,bigint>& mess,const Random_Coins& rc) const
|
||||
{
|
||||
@@ -137,6 +144,7 @@ void FHE_PK::encrypt(Ciphertext& c,
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_PK::encrypt(Ciphertext& c,
|
||||
const Plaintext<gf2n_short,P2Data,int>& mess,const Random_Coins& rc) const
|
||||
{
|
||||
@@ -205,6 +213,7 @@ Ciphertext FHE_PK::encrypt(
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_SK::decrypt(Plaintext<gfp,FFT_Data,bigint>& mess,const Ciphertext& c) const
|
||||
{
|
||||
if (&c.get_params()!=params) { throw params_mismatch(); }
|
||||
@@ -220,6 +229,7 @@ void FHE_SK::decrypt(Plaintext<gfp,FFT_Data,bigint>& mess,const Ciphertext& c) c
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_SK::decrypt(Plaintext<gfp,PPData,bigint>& mess,const Ciphertext& c) const
|
||||
{
|
||||
if (&c.get_params()!=params) { throw params_mismatch(); }
|
||||
@@ -234,6 +244,7 @@ void FHE_SK::decrypt(Plaintext<gfp,PPData,bigint>& mess,const Ciphertext& c) con
|
||||
|
||||
|
||||
|
||||
template<>
|
||||
void FHE_SK::decrypt(Plaintext<gf2n_short,P2Data,int>& mess,const Ciphertext& c) const
|
||||
{
|
||||
if (&c.get_params()!=params) { throw params_mismatch(); }
|
||||
@@ -243,7 +254,8 @@ void FHE_SK::decrypt(Plaintext<gf2n_short,P2Data,int>& mess,const Ciphertext& c)
|
||||
|
||||
mul(ans,c.c1(),sk);
|
||||
sub(ans,c.c0(),ans);
|
||||
mess.set_poly_mod(ans.to_vec_bigint(),ans.get_modulus());
|
||||
ans.change_rep(polynomial);
|
||||
mess.set_poly_mod(ans.get_iterator(), ans.get_modulus());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,9 +48,8 @@ class FHE_SK
|
||||
// Assumes Ring and prime of mess have already been set correctly
|
||||
// Ciphertext c must be at level 0 or an error occurs
|
||||
// c must have same params as SK
|
||||
void decrypt(Plaintext<gfp,FFT_Data,bigint>& mess,const Ciphertext& c) const;
|
||||
void decrypt(Plaintext<gfp,PPData,bigint>& mess,const Ciphertext& c) const;
|
||||
void decrypt(Plaintext<gf2n_short,P2Data,int>& mess,const Ciphertext& c) const;
|
||||
template<class T, class FD, class S>
|
||||
void decrypt(Plaintext<T, FD, S>& mess,const Ciphertext& c) const;
|
||||
|
||||
template <class FD>
|
||||
Plaintext<typename FD::T, FD, typename FD::S> decrypt(const Ciphertext& c, const FD& FieldD);
|
||||
@@ -121,9 +120,8 @@ class FHE_PK
|
||||
|
||||
|
||||
// c must have same params as PK and rc
|
||||
void encrypt(Ciphertext& c, const Plaintext<gfp,FFT_Data,bigint>& mess, const Random_Coins& rc) const;
|
||||
void encrypt(Ciphertext& c, const Plaintext<gfp,PPData,bigint>& mess, const Random_Coins& rc) const;
|
||||
void encrypt(Ciphertext& c, const Plaintext<gf2n_short,P2Data,int>& mess, const Random_Coins& rc) const;
|
||||
template <class T, class FD, class S>
|
||||
void encrypt(Ciphertext& c, const Plaintext<T, FD, S>& mess, const Random_Coins& rc) const;
|
||||
|
||||
template <class S>
|
||||
void encrypt(Ciphertext& c, const vector<S>& mess, const Random_Coins& rc) const;
|
||||
@@ -164,4 +162,22 @@ class FHE_PK
|
||||
// PK and SK must have the same params, otherwise an error
|
||||
void KeyGen(FHE_PK& PK,FHE_SK& SK,PRNG& G);
|
||||
|
||||
|
||||
class FHE_KeyPair
|
||||
{
|
||||
public:
|
||||
FHE_PK pk;
|
||||
FHE_SK sk;
|
||||
|
||||
FHE_KeyPair(const FHE_Params& params, const bigint& pr = 0) :
|
||||
pk(params, pr), sk(params, pr)
|
||||
{
|
||||
}
|
||||
|
||||
void generate(PRNG& G)
|
||||
{
|
||||
KeyGen(pk, sk, G);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,7 @@ void ident(matrix& U,int n)
|
||||
|
||||
void ident(imatrix& U,int n)
|
||||
{
|
||||
U.resize(n, vector<int>(n) );
|
||||
U.resize(n, imatrix::value_type(n));
|
||||
for (int i=0; i<n; i++)
|
||||
{ for (int j=0; j<n; j++)
|
||||
{ U[i][j]=0; }
|
||||
@@ -299,20 +299,17 @@ void pinv(imatrix& Ai,const imatrix& B)
|
||||
while (A[k][c]==0) { k++; }
|
||||
// Swap rows if needed
|
||||
if (k!=r)
|
||||
{ for (int i=0; i<nc; i++)
|
||||
{ int t=A[r][i]; A[r][i]=A[k][i]; A[k][i]=t; }
|
||||
for (int i=0; i<nr; i++)
|
||||
{ int t=Ai[r][i]; Ai[r][i]=Ai[k][i]; Ai[k][i]=t; }
|
||||
}
|
||||
{
|
||||
A[r].swap(A[k]);
|
||||
Ai[r].swap(Ai[k]);
|
||||
}
|
||||
// Kill off all rows above and below with a one in this position
|
||||
for (k=0; k<nr; k++)
|
||||
{ if (k!=r && A[k][c]==1)
|
||||
{ // Only have to go from c onwards as rest are done
|
||||
for (int i=c; i<nc; i++)
|
||||
{ A[k][i]^=A[r][i]; }
|
||||
A[k].add(A[r]);
|
||||
// Need to do all cols here
|
||||
for (int i=0; i<nr; i++)
|
||||
{ Ai[k][i]^=Ai[r][i]; }
|
||||
Ai[k].add(Ai[r]);
|
||||
}
|
||||
}
|
||||
r++; c++;
|
||||
@@ -336,11 +333,22 @@ bool imatrix::operator!=(const imatrix& other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void imatrix::hash(octetStream& o) const
|
||||
{
|
||||
Hash hash;
|
||||
for (auto& row : *this)
|
||||
hash.update(row.get_ptr(), row.size_bytes());
|
||||
o.concat(hash.final());
|
||||
}
|
||||
|
||||
void imatrix::pack(octetStream& o) const
|
||||
{
|
||||
o.store(size());
|
||||
for (auto& x : *this)
|
||||
o.store(x);
|
||||
{
|
||||
assert(x.size() == size());
|
||||
x.pack(o);
|
||||
}
|
||||
}
|
||||
|
||||
void imatrix::unpack(octetStream& o)
|
||||
@@ -349,7 +357,10 @@ void imatrix::unpack(octetStream& o)
|
||||
o.get(size);
|
||||
resize(size);
|
||||
for (auto& x : *this)
|
||||
o.get(x);
|
||||
{
|
||||
x.resize(size);
|
||||
x.unpack(o);
|
||||
}
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& s,const imatrix& A)
|
||||
@@ -367,10 +378,14 @@ istream& operator>>(istream& s,imatrix& A)
|
||||
{
|
||||
int r,c;
|
||||
s >> r >> c;
|
||||
A.resize(r, vector<int>(c) );
|
||||
A.resize(r, imatrix::value_type(c) );
|
||||
for (int i=0; i<r; i++)
|
||||
{ for (int j=0; j<c; j++)
|
||||
{ s >> A[i][j]; }
|
||||
{
|
||||
bool b;
|
||||
s >> b;
|
||||
A[i][j] = b;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -7,15 +7,17 @@ using namespace std;
|
||||
|
||||
#include "Math/bigint.h"
|
||||
#include "Math/modp.h"
|
||||
#include "OT/BitVector.h"
|
||||
|
||||
typedef vector< vector<bigint> > matrix;
|
||||
typedef vector< vector<modp> > modp_matrix;
|
||||
|
||||
class imatrix : public vector< vector<int> >
|
||||
class imatrix : public vector< BitVector >
|
||||
{
|
||||
public:
|
||||
bool operator!=(const imatrix& other) const;
|
||||
|
||||
void hash(octetStream& o) const;
|
||||
void pack(octetStream& o) const;
|
||||
void unpack(octetStream& o);
|
||||
};
|
||||
|
||||
@@ -112,7 +112,7 @@ int generate_semi_setup(int plaintext_length, int sec,
|
||||
{
|
||||
if (params.n_mults() > 0)
|
||||
throw runtime_error("only implemented for 0-level BGV");
|
||||
gf2n::init_field(plaintext_length);
|
||||
gf2n_short::init_field(plaintext_length);
|
||||
int m;
|
||||
char_2_dimension(m, plaintext_length);
|
||||
SemiHomomorphicNoiseBounds nb(2, phi_N(m), 1, sec,
|
||||
@@ -417,10 +417,10 @@ GF2X Subs_PowX_Mod(const GF2X& a,int pow,int m,const GF2X& c)
|
||||
void init(P2Data& P2D,const Ring& Rg)
|
||||
{
|
||||
GF2X G,F;
|
||||
SetCoeff(G,gf2n::degree(),1);
|
||||
SetCoeff(G,gf2n_short::degree(),1);
|
||||
SetCoeff(G,0,1);
|
||||
for (int i=0; i<gf2n::get_nterms(); i++)
|
||||
{ SetCoeff(G,gf2n::get_t(i),1); }
|
||||
for (int i=0; i<gf2n_short::get_nterms(); i++)
|
||||
{ SetCoeff(G,gf2n_short::get_t(i),1); }
|
||||
//cout << "G = " << G << endl;
|
||||
|
||||
for (int i=0; i<=Rg.phi_m(); i++)
|
||||
@@ -451,8 +451,8 @@ void init(P2Data& P2D,const Ring& Rg)
|
||||
if (Gord!=e) { cout << "Group order wrong, need to repeat the Haf-Mc algorithm" << endl; seed++; }
|
||||
}
|
||||
//cout << " l = " << Gord << " , d = " << d << endl;
|
||||
if ((Gord*gf2n::degree())!=Rg.phi_m())
|
||||
{ cout << "Plaintext type requires Gord*gf2n::degree == phi_m" << endl;
|
||||
if ((Gord*gf2n_short::degree())!=Rg.phi_m())
|
||||
{ cout << "Plaintext type requires Gord*gf2n_short::degree == phi_m" << endl;
|
||||
throw not_implemented();
|
||||
}
|
||||
|
||||
@@ -514,9 +514,11 @@ void init(P2Data& P2D,const Ring& Rg)
|
||||
// This is a deg(F) x (deg(G)*Gord) matrix which maps elements
|
||||
// vectors in the SIMD representation into plaintext vectors
|
||||
|
||||
P2D.A.resize(Rg.phi_m(), vector<int>(Gord*gf2n::degree()));
|
||||
imatrix A;
|
||||
A.resize(Rg.phi_m(), imatrix::value_type(Gord*gf2n_short::degree()));
|
||||
P2D.A.resize(A[0].size(), imatrix::value_type(A.size()));
|
||||
for (int slot=0; slot<Gord; slot++)
|
||||
{ for (int co=0; co<gf2n::degree(); co++)
|
||||
{ for (int co=0; co<gf2n_short::degree(); co++)
|
||||
{ // Work out how x^co in given slot maps to plaintext vector
|
||||
GF2X av;
|
||||
SetCoeff(av,co,1);
|
||||
@@ -526,18 +528,21 @@ void init(P2Data& P2D,const Ring& Rg)
|
||||
av=MulMod(av,u[slot],F);
|
||||
//cout << slot << " " << co << " : " << av << endl;
|
||||
for (int k=0; k<Rg.phi_m(); k++)
|
||||
{ if (IsOne(coeff(av,k)))
|
||||
{ P2D.A[k][slot*gf2n::degree()+co]=1; }
|
||||
{
|
||||
int i = slot*gf2n_short::degree()+co;
|
||||
if (IsOne(coeff(av,k)))
|
||||
{ A[k][i]=1; }
|
||||
else
|
||||
{ P2D.A[k][slot*gf2n::degree()+co]=0; }
|
||||
{ A[k][i]=0; }
|
||||
P2D.A[i][k] = A[k][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
//cout << "Forward Matrix : " << endl; print(P2D.A);
|
||||
|
||||
// Find pseudo inverse modulo 2
|
||||
pinv(P2D.Ai,P2D.A);
|
||||
P2D.Ai.resize(Gord*gf2n::degree());
|
||||
pinv(P2D.Ai, A);
|
||||
P2D.Ai.resize(Gord*gf2n_short::degree());
|
||||
|
||||
//cout << "Inverse Matrix : " << endl; print(P2D.Ai);
|
||||
|
||||
@@ -624,7 +629,7 @@ void SPDZ_Data_Setup_Char_2(Ring& R, P2Data& P2D, bigint& pr0, bigint& pr1,
|
||||
cout << "\t\tpr1 mod m = " << pr1%m << endl;
|
||||
cout << "\t\tpr1 mod 2^lg2m = " << pr1%(1<<lg2m) << endl;
|
||||
|
||||
gf2n::init_field(lg2);
|
||||
gf2n_short::init_field(lg2);
|
||||
load_or_generate(P2D, R);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,26 +8,29 @@ void P2Data::forward(vector<int>& ans,const vector<gf2n_short>& a) const
|
||||
{
|
||||
int n=gf2n_short::degree();
|
||||
|
||||
BitVector bv(A.size());
|
||||
ans.resize(A.size());
|
||||
for (unsigned i=0; i<A.size(); i++)
|
||||
{ ans[i]=0; }
|
||||
for (int i=0; i<slots; i++)
|
||||
{ word rep=a[i].get();
|
||||
for (int j=0; j<n && rep!=0; j++)
|
||||
{ if ((rep&1)==1)
|
||||
{ int jj=i*n+j;
|
||||
for (unsigned k=0; k<A.size(); k++)
|
||||
{ if (A[k][jj]==1) { ans[k]=ans[k]^1; } }
|
||||
bv.add(A[jj]);
|
||||
}
|
||||
rep>>=1;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < bv.size(); i++)
|
||||
ans[i] = bv.get_bit(i);
|
||||
}
|
||||
|
||||
|
||||
void P2Data::backward(vector<gf2n_short>& ans,const vector<int>& a) const
|
||||
{
|
||||
int n=gf2n_short::degree();
|
||||
BitVector bv(a.size());
|
||||
for (size_t i = 0; i < a.size(); i++)
|
||||
bv.set_bit(i, a[i]);
|
||||
|
||||
ans.resize(slots);
|
||||
word y;
|
||||
@@ -35,10 +38,8 @@ void P2Data::backward(vector<gf2n_short>& ans,const vector<int>& a) const
|
||||
{ y=0;
|
||||
for (int j=0; j<n; j++)
|
||||
{ y<<=1;
|
||||
int ii=i*n+n-1-j,xx=0;
|
||||
for (unsigned int k=0; k<a.size(); k++)
|
||||
{ if ((a[k] & 1) && Ai[ii][k]==1) { xx^=1; } }
|
||||
y^=xx;
|
||||
int ii = i * n + n - 1 - j;
|
||||
y ^= (Ai[ii] & bv).parity();
|
||||
}
|
||||
ans[i].assign(y);
|
||||
}
|
||||
@@ -47,7 +48,7 @@ void P2Data::backward(vector<gf2n_short>& ans,const vector<int>& a) const
|
||||
|
||||
void P2Data::check_dimensions() const
|
||||
{
|
||||
// cout << "degree: " << gf2n::degree() << endl;
|
||||
// cout << "degree: " << gf2n_short::degree() << endl;
|
||||
// cout << "slots: " << slots << endl;
|
||||
// cout << "A: " << A.size() << "x" << A[0].size() << endl;
|
||||
// cout << "Ai: " << Ai.size() << "x" << Ai[0].size() << endl;
|
||||
@@ -57,8 +58,11 @@ void P2Data::check_dimensions() const
|
||||
throw runtime_error("forward mapping not square");
|
||||
if (Ai.size() != Ai[0].size())
|
||||
throw runtime_error("backward mapping not square");
|
||||
if ((int)A[0].size() != slots * gf2n::degree())
|
||||
throw runtime_error("mapping dimension incorrect");
|
||||
if ((int)A[0].size() != slots * gf2n_short::degree())
|
||||
throw runtime_error(
|
||||
"mapping dimension incorrect: " + to_string(A[0].size())
|
||||
+ " != " + to_string(slots) + " * "
|
||||
+ to_string(gf2n_short::degree()));
|
||||
}
|
||||
|
||||
|
||||
@@ -67,19 +71,35 @@ bool P2Data::operator!=(const P2Data& other) const
|
||||
return slots != other.slots or A != other.A or Ai != other.Ai;
|
||||
}
|
||||
|
||||
void P2Data::hash(octetStream& o) const
|
||||
{
|
||||
check_dimensions();
|
||||
o.store(gf2n_short::degree());
|
||||
o.store(slots);
|
||||
A.hash(o);
|
||||
Ai.hash(o);
|
||||
}
|
||||
|
||||
void P2Data::pack(octetStream& o) const
|
||||
{
|
||||
check_dimensions();
|
||||
o.store(gf2n_short::degree());
|
||||
o.store(slots);
|
||||
A.pack(o);
|
||||
Ai.pack(o);
|
||||
o.store_int(0xdeadbeef1, 8);
|
||||
}
|
||||
|
||||
void P2Data::unpack(octetStream& o)
|
||||
{
|
||||
int degree;
|
||||
o.get(degree);
|
||||
gf2n_short::init_field(degree);
|
||||
o.get(slots);
|
||||
A.unpack(o);
|
||||
Ai.unpack(o);
|
||||
if (o.get_int(8) != 0xdeadbeef1)
|
||||
throw runtime_error("P2Data serialization incorrect");
|
||||
check_dimensions();
|
||||
}
|
||||
|
||||
@@ -103,8 +123,8 @@ istream& operator>>(istream& s,P2Data& P2D)
|
||||
|
||||
string get_filename(const Ring& Rg)
|
||||
{
|
||||
return (string) PREP_DIR + "P2D-" + to_string(gf2n::degree()) + "x"
|
||||
+ to_string(Rg.phi_m() / gf2n::degree());
|
||||
return (string) PREP_DIR + "P2D-" + to_string(gf2n_short::degree()) + "x"
|
||||
+ to_string(Rg.phi_m() / gf2n_short::degree());
|
||||
}
|
||||
|
||||
void P2Data::load(const Ring& Rg)
|
||||
@@ -114,8 +134,6 @@ void P2Data::load(const Ring& Rg)
|
||||
ifstream s(filename);
|
||||
octetStream os;
|
||||
os.input(s);
|
||||
if (s.eof() or s.fail())
|
||||
throw runtime_error("cannot load P2Data");
|
||||
unpack(os);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
class P2Data
|
||||
{
|
||||
int slots;
|
||||
// Data for the forward mapping (phi_m by (slots*gf2n:deg))
|
||||
// Data for the forward mapping ((slots*gf2n:deg) by phi_m)
|
||||
imatrix A;
|
||||
// Data for the backward mapping (phi_m by phi_m)
|
||||
imatrix Ai;
|
||||
@@ -22,8 +22,8 @@ class P2Data
|
||||
typedef int S;
|
||||
|
||||
int num_slots() const { return slots; }
|
||||
int degree() const { return A.size() ? A[0].size() : 0; }
|
||||
int phi_m() const { return A.size(); }
|
||||
int degree() const { return A.size() ? A.size() : 0; }
|
||||
int phi_m() const { return A[0].size(); }
|
||||
|
||||
void check_dimensions() const;
|
||||
|
||||
@@ -39,6 +39,7 @@ class P2Data
|
||||
// no op because we require field to be initalized first
|
||||
void init_field() const {}
|
||||
|
||||
void hash(octetStream& o) const;
|
||||
void pack(octetStream& o) const;
|
||||
void unpack(octetStream& o);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
#include "FHE/Plaintext.h"
|
||||
#include "FHE/Ring_Element.h"
|
||||
#include "FHE/PPData.h"
|
||||
#include "FHE/P2Data.h"
|
||||
|
||||
|
||||
template<>
|
||||
@@ -211,6 +213,22 @@ void Plaintext<gf2n_short,P2Data,int>::set_poly_mod(const vector<bigint>& vv,con
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void Plaintext<gf2n_short,P2Data,int>::set_poly_mod(const Generator<bigint>& generator,const bigint& mod)
|
||||
{
|
||||
allocate(Polynomial);
|
||||
bigint half_mod = mod / 2;
|
||||
bigint te;
|
||||
for (unsigned int i=0; i<b.size(); i++)
|
||||
{
|
||||
generator.get(te);
|
||||
if (te > half_mod)
|
||||
te -= mod;
|
||||
b[i]=isOdd(te);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rand_poly(vector<bigint>& b,PRNG& G,const bigint& pr,bool positive=true)
|
||||
{
|
||||
for (unsigned int i=0; i<b.size(); i++)
|
||||
@@ -386,6 +404,15 @@ void Plaintext<T,FD,S>::assign_one(PT_Type t)
|
||||
}
|
||||
}
|
||||
|
||||
template<class T,class FD,class S>
|
||||
void Plaintext<T,FD,S>::assign_constant(T constant, PT_Type t)
|
||||
{
|
||||
allocate(Evaluation);
|
||||
for (auto& x : a)
|
||||
x = constant;
|
||||
if (t != Evaluation)
|
||||
to_poly();
|
||||
}
|
||||
|
||||
template<class T,class FD,class S>
|
||||
Plaintext<T,FD,S>& Plaintext<T,FD,S>::operator+=(
|
||||
@@ -399,10 +426,7 @@ Plaintext<T,FD,S>& Plaintext<T,FD,S>::operator+=(
|
||||
if (b.size() != y.b.size())
|
||||
throw length_error("size mismatch");
|
||||
|
||||
for (unsigned int i = 0; i < b.size(); i++)
|
||||
b[i] += y.b[i];
|
||||
|
||||
type = Polynomial;
|
||||
add(*this, *this, y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -487,9 +511,8 @@ void add(Plaintext<gf2n_short,P2Data,int>& z,const Plaintext<gf2n_short,P2Data,i
|
||||
}
|
||||
if (z.type!=Evaluation)
|
||||
{ for (unsigned int i=0; i<z.b.size(); i++)
|
||||
{ z.b[i]=x.b[i]+y.b[i];
|
||||
if (z.b[i]==2)
|
||||
{ z.b[i]=0; }
|
||||
{
|
||||
z.b[i]=x.b[i] ^ y.b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,9 +603,8 @@ void sub(Plaintext<gf2n_short,P2Data,int>& z,const Plaintext<gf2n_short,P2Data,i
|
||||
}
|
||||
if (z.type!=Evaluation)
|
||||
{ for (unsigned int i=0; i<z.b.size(); i++)
|
||||
{ z.b[i]=x.b[i]-y.b[i];
|
||||
if (z.b[i]<0)
|
||||
{ z.b[i]=1; }
|
||||
{
|
||||
z.b[i]=x.b[i] ^ y.b[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,6 @@
|
||||
* deal with
|
||||
*/
|
||||
|
||||
#include "Math/bigint.h"
|
||||
#include "FHE/FFT_Data.h"
|
||||
#include "FHE/P2Data.h"
|
||||
#include "FHE/PPData.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "FHE/Generator.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -148,6 +142,7 @@ class Plaintext
|
||||
|
||||
void assign_zero(PT_Type t = Evaluation);
|
||||
void assign_one(PT_Type t = Evaluation);
|
||||
void assign_constant(T constant, PT_Type t = Evaluation);
|
||||
|
||||
friend void add<>(Plaintext<T,FD,S>& z,const Plaintext<T,FD,S>& x,const Plaintext<T,FD,S>& y);
|
||||
friend void sub<>(Plaintext<T,FD,S>& z,const Plaintext<T,FD,S>& x,const Plaintext<T,FD,S>& y);
|
||||
|
||||
@@ -6,39 +6,22 @@
|
||||
void reduce_step(vector<modp>& aa,int i,const FFT_Data& FFTD)
|
||||
{ modp temp=aa[i];
|
||||
for (int j=0; j<FFTD.phi_m(); j++)
|
||||
{ switch (FFTD.Phi()[j])
|
||||
{ case 0:
|
||||
break;
|
||||
case 1:
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
case -1:
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
case 2:
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
case -2:
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
case 3:
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
case -3:
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
break;
|
||||
default:
|
||||
throw not_implemented();
|
||||
}
|
||||
{
|
||||
if (FFTD.Phi()[j] > 0)
|
||||
for (int k = 0; k < FFTD.Phi()[j]; k++)
|
||||
Sub(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
else
|
||||
for (int k = 0; k < abs(FFTD.Phi()[j]); k++)
|
||||
Add(aa[i-FFTD.phi_m()+j],aa[i-FFTD.phi_m()+j],temp,FFTD.get_prD());
|
||||
}
|
||||
}
|
||||
|
||||
void reduce(vector<modp>& aa, int top, int bottom, const FFT_Data& FFTD)
|
||||
{
|
||||
for (int i = top - 1; i >= bottom; i--)
|
||||
reduce_step(aa, i, FFTD);
|
||||
}
|
||||
|
||||
|
||||
Ring_Element::Ring_Element(const FFT_Data& fftd,RepType r)
|
||||
{
|
||||
@@ -129,10 +112,7 @@ void mul(Ring_Element& ans,const Ring_Element& a,const Ring_Element& b)
|
||||
}
|
||||
}
|
||||
// Now apply reduction, assumes Ring.poly is monic
|
||||
for (int i=2*(*a.FFTD).phi_m()-1; i>=(*a.FFTD).phi_m(); i--)
|
||||
{ reduce_step(aa,i,*a.FFTD);
|
||||
assignZero(aa[i],(*a.FFTD).get_prD());
|
||||
}
|
||||
reduce(aa, 2*(*a.FFTD).phi_m(), (*a.FFTD).phi_m(), *a.FFTD);
|
||||
// Now stick into answer
|
||||
for (int i=0; i<(*ans.FFTD).phi_m(); i++)
|
||||
{ ans.element[i]=aa[i]; }
|
||||
@@ -296,8 +276,7 @@ void Ring_Element::change_rep(RepType r)
|
||||
{ fft[(*FFTD).p(i)]=element[i]; }
|
||||
BFFT(fft,fft,*FFTD,false);
|
||||
// Need to reduce fft mod Phi_m
|
||||
for (int i=(*FFTD).m()-1; i>=(*FFTD).phi_m(); i--)
|
||||
{ reduce_step(fft,i,*FFTD); }
|
||||
reduce(fft, (*FFTD).m(), (*FFTD).phi_m(), *FFTD);
|
||||
for (int i=0; i<(*FFTD).phi_m(); i++)
|
||||
{ element[i]=fft[i]; }
|
||||
}
|
||||
|
||||
@@ -69,12 +69,6 @@ protected:
|
||||
~Rq_Element()
|
||||
{ ; }
|
||||
|
||||
// Copy Assignment
|
||||
Rq_Element& operator=(const Rq_Element& e)
|
||||
{ if (this!=&e) { assign(e); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Ring_Element& get(int i) const { return a[i]; }
|
||||
|
||||
/* Functional Operators */
|
||||
@@ -84,6 +78,9 @@ protected:
|
||||
friend void mul(Rq_Element& ans,const Rq_Element& a,const Rq_Element& b);
|
||||
friend void mul(Rq_Element& ans,const Rq_Element& a,const bigint& b);
|
||||
|
||||
template<class S>
|
||||
Rq_Element& operator+=(const vector<S>& other);
|
||||
|
||||
Rq_Element& operator+=(const Rq_Element& other) { add(*this, *this, other); return *this; }
|
||||
|
||||
Rq_Element operator+(const Rq_Element& b) const { Rq_Element res(*this); add(res, *this, b); return res; }
|
||||
@@ -155,5 +152,13 @@ template<int L>
|
||||
inline void mul(Rq_Element& ans,const bigint& a,const Rq_Element& b)
|
||||
{ mul(ans,b,a); }
|
||||
|
||||
#endif
|
||||
template<class S>
|
||||
Rq_Element& Rq_Element::operator+=(const vector<S>& other)
|
||||
{
|
||||
Rq_Element tmp = *this;
|
||||
tmp.from_vec(other, lev);
|
||||
add(*this, *this, tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <FHEOffline/DataSetup.h>
|
||||
#include "FHEOffline/DistKeyGen.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
#include "FHE/NTL-Subs.h"
|
||||
#include "Tools/benchmarking.h"
|
||||
|
||||
@@ -69,7 +69,7 @@ void PartSetup<FD>::generate_setup(int n_parties, int plaintext_length, int sec,
|
||||
void DataSetup::write_setup(string dir, bool skip_2)
|
||||
{
|
||||
ofstream outf;
|
||||
write_online_setup(outf, dir, FTD.get_prime(), gf2n::degree());
|
||||
write_online_setup(outf, dir, FTD.get_prime(), gf2n_short::degree());
|
||||
setup_p.output_setup(outf);
|
||||
if (not skip_2)
|
||||
setup_2.output_setup(outf);
|
||||
@@ -83,7 +83,7 @@ void DataSetup::write_setup(bool skip_2)
|
||||
string DataSetup::get_prep_dir(int n_parties) const
|
||||
{
|
||||
return ::get_prep_dir(n_parties, FTD.get_prime().numBits(),
|
||||
gf2n::degree());
|
||||
gf2n_short::degree());
|
||||
}
|
||||
|
||||
void DataSetup::write_setup(const Names& N, bool skip_2)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "DistDecrypt.h"
|
||||
#include "FHE/P2Data.h"
|
||||
|
||||
template<class FD>
|
||||
DistDecrypt<FD>::DistDecrypt(const Player& P, const FHE_SK& share,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <FHEOffline/DistKeyGen.h>
|
||||
#include "Auth/Subroutines.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
|
||||
/*
|
||||
* This creates the "pseudo-encryption" of the R_q element mess,
|
||||
@@ -189,7 +189,7 @@ void DistKeyGen::finalize(FHE_PK& pk, FHE_SK& sk)
|
||||
sk.assign(secret);
|
||||
}
|
||||
|
||||
void DistKeyGen::check_equality(const DistKeyGen other)
|
||||
void DistKeyGen::check_equality(const DistKeyGen& other)
|
||||
{
|
||||
if (a != other.a)
|
||||
throw runtime_error("no match at a");
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
void compute_enc();
|
||||
void sum_enc(const vector<Ciphertext>& enc);
|
||||
void finalize(FHE_PK& pk, FHE_SK& sk);
|
||||
void check_equality(const DistKeyGen other);
|
||||
void check_equality(const DistKeyGen& other);
|
||||
};
|
||||
|
||||
#endif /* FHEOFFLINE_DISTKEYGEN_H_ */
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
#include "Auth/Subroutines.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/random.h"
|
||||
|
||||
#include "EncCommit.h"
|
||||
#include "FHE/P2Data.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -73,7 +74,14 @@ void EncCommit<T,FD,S>::init(const Player& PP,const FHE_PK& fhepk,condition cc,c
|
||||
template<class T,class FD,class S>
|
||||
void EncCommit<T,FD,S>::next_covert(Plaintext<T,FD,S>& mess, vector<Ciphertext>& C) const
|
||||
{
|
||||
const FHE_Params& params=(*pk).get_params();
|
||||
covert_generation(mess, C, {size_t(P->num_players()), pk}, P, num_runs, cond);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void covert_generation(Plaintext_<FD>& mess, vector<Ciphertext>& C,
|
||||
const vector<const FHE_PK*>& pks, const Player* P, int num_runs, condition cond)
|
||||
{
|
||||
const FHE_Params& params=(*pks[0]).get_params();
|
||||
|
||||
/* Commit to the seeds */
|
||||
vector< vector<octetStream> > seeds(num_runs, vector<octetStream>((*P).num_players()));
|
||||
@@ -84,13 +92,13 @@ void EncCommit<T,FD,S>::next_covert(Plaintext<T,FD,S>& mess, vector<Ciphertext>&
|
||||
Commit_To_Seeds(G,seeds,Comm_seeds,Open_seeds,*P,num_runs);
|
||||
|
||||
// Generate the messages and ciphertexts
|
||||
vector< Plaintext<T,FD,S> > m(num_runs,mess.get_field());
|
||||
vector< Plaintext_<FD> > m(num_runs,mess.get_field());
|
||||
vector<Ciphertext> c(num_runs,params);
|
||||
Random_Coins rc(params);
|
||||
for (int i=0; i<num_runs; i++)
|
||||
{ m[i].randomize(G[i],cond);
|
||||
rc.generate(G[i]);
|
||||
(*pk).encrypt(c[i],m[i],rc);
|
||||
(*pks[P->my_num()]).encrypt(c[i],m[i],rc);
|
||||
//cout << "xxxxxxxxxxxxxxxxxxxxx" << endl;
|
||||
//cout << i << "\t" << (*P).socket(P.my_num()) << endl;
|
||||
//cout << i << "\t" << m[i] << endl;
|
||||
@@ -118,7 +126,7 @@ void EncCommit<T,FD,S>::next_covert(Plaintext<T,FD,S>& mess, vector<Ciphertext>&
|
||||
Open(seeds,Comm_seeds,Open_seeds,*P,num_runs,challenge);
|
||||
|
||||
// Now check all the prior executions
|
||||
Plaintext<T,FD,S> mm(mess.get_field());
|
||||
Plaintext_<FD> mm(mess.get_field());
|
||||
Ciphertext cc(params);
|
||||
octetStream occ;
|
||||
for (int i=0; i<num_runs; i++)
|
||||
@@ -130,7 +138,7 @@ void EncCommit<T,FD,S>::next_covert(Plaintext<T,FD,S>& mess, vector<Ciphertext>&
|
||||
//cout << "GOT SEED : " << i << " " << j << " " << P.socket(j) << seeds[i][j] << endl;
|
||||
mm.randomize(G,cond);
|
||||
rc.generate(G);
|
||||
(*pk).encrypt(cc,mm,rc);
|
||||
(*pks[j]).encrypt(cc,mm,rc);
|
||||
occ.reset_write_head();
|
||||
cc.pack(occ);
|
||||
if (!occ.equals(ctx[i][j]))
|
||||
|
||||
@@ -130,6 +130,9 @@ class EncCommit : public EncCommitBase<T,FD,S>
|
||||
template <class FD>
|
||||
using EncCommit_ = EncCommit<typename FD::T, FD, typename FD::S>;
|
||||
|
||||
template <class FD>
|
||||
void covert_generation(Plaintext_<FD>& mess, vector<Ciphertext>& C,
|
||||
const vector<const FHE_PK*>& pks, const Player* P, int num_runs, condition cond);
|
||||
|
||||
template <class FD>
|
||||
void generate_mac_key(typename FD::T& key_share, Ciphertext& key, const FD& FieldD,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#include "Auth/Subroutines.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
#include "FHE/Rq_Element.h"
|
||||
#include "FHE/Ciphertext.h"
|
||||
#include "Tools/Commit.h"
|
||||
|
||||
@@ -40,7 +40,7 @@ void get_setup(FHE_Params& params_p,FFT_Data& FTD,
|
||||
if (!skip_2)
|
||||
{
|
||||
// initialize before reading P2D for consistency check
|
||||
gf2n::init_field(lg2);
|
||||
gf2n_short::init_field(lg2);
|
||||
inpf >> R2;
|
||||
inpf >> P2D;
|
||||
if (R2.phi_m() != P2D.phi_m())
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
template <class FD>
|
||||
Multiplier<FD>::Multiplier(int offset, PairwiseGenerator<FD>& generator) :
|
||||
generator(generator), machine(generator.machine),
|
||||
P(generator.global_player, offset),
|
||||
num_players(generator.global_player.num_players()),
|
||||
my_num(generator.global_player.my_num()),
|
||||
P(generator.P, offset),
|
||||
num_players(generator.P.num_players()),
|
||||
my_num(generator.P.my_num()),
|
||||
other_pk(machine.other_pks[(my_num + num_players - offset) % num_players]),
|
||||
other_enc_alpha(machine.enc_alphas[(my_num + num_players - offset) % num_players]),
|
||||
timers(generator.timers),
|
||||
@@ -34,39 +34,54 @@ void Multiplier<FD>::multiply_and_add(Plaintext_<FD>& res,
|
||||
|
||||
template <class FD>
|
||||
void Multiplier<FD>::multiply_and_add(Plaintext_<FD>& res,
|
||||
const Ciphertext& enc_a, const Rq_Element& b)
|
||||
const Ciphertext& enc_a, const Rq_Element& b, OT_ROLE role)
|
||||
{
|
||||
PRNG G;
|
||||
G.ReSeed();
|
||||
timers["Ciphertext multiplication"].start();
|
||||
C.mul(enc_a, b);
|
||||
timers["Ciphertext multiplication"].stop();
|
||||
timers["Mask randomization"].start();
|
||||
product_share.randomize(G);
|
||||
bigint B = 6 * machine.setup<FD>().params.get_R();
|
||||
B *= machine.setup<FD>().FieldD.get_prime();
|
||||
B <<= machine.sec;
|
||||
// slack
|
||||
B *= NonInteractiveProof::slack(machine.sec,
|
||||
machine.setup<FD>().params.phi_m());
|
||||
B <<= machine.extra_slack;
|
||||
rc.generateUniform(G, 0, B, B);
|
||||
timers["Mask randomization"].stop();
|
||||
timers["Encryption"].start();
|
||||
other_pk.encrypt(mask, product_share, rc);
|
||||
timers["Encryption"].stop();
|
||||
timers["Multiplied ciphertext sending"].start();
|
||||
octetStream o;
|
||||
mask += C;
|
||||
mask.pack(o);
|
||||
P.reverse_exchange(o);
|
||||
C.unpack(o);
|
||||
|
||||
if (role & SENDER)
|
||||
{
|
||||
PRNG G;
|
||||
G.ReSeed();
|
||||
timers["Ciphertext multiplication"].start();
|
||||
C.mul(enc_a, b);
|
||||
timers["Ciphertext multiplication"].stop();
|
||||
timers["Mask randomization"].start();
|
||||
product_share.randomize(G);
|
||||
bigint B = 6 * machine.setup<FD>().params.get_R();
|
||||
B *= machine.setup<FD>().FieldD.get_prime();
|
||||
B <<= machine.drown_sec;
|
||||
// slack
|
||||
B *= NonInteractiveProof::slack(machine.sec,
|
||||
machine.setup<FD>().params.phi_m());
|
||||
B <<= machine.extra_slack;
|
||||
rc.generateUniform(G, 0, B, B);
|
||||
timers["Mask randomization"].stop();
|
||||
timers["Encryption"].start();
|
||||
other_pk.encrypt(mask, product_share, rc);
|
||||
timers["Encryption"].stop();
|
||||
mask += C;
|
||||
mask.pack(o);
|
||||
res -= product_share;
|
||||
}
|
||||
|
||||
timers["Multiplied ciphertext sending"].start();
|
||||
if (role == BOTH)
|
||||
P.reverse_exchange(o);
|
||||
else if (role == SENDER)
|
||||
P.reverse_send(o);
|
||||
else if (role == RECEIVER)
|
||||
P.receive(o);
|
||||
timers["Multiplied ciphertext sending"].stop();
|
||||
timers["Decryption"].start();
|
||||
res -= product_share;
|
||||
machine.sk.decrypt_any(product_share, C);
|
||||
res += product_share;
|
||||
timers["Decryption"].stop();
|
||||
|
||||
if (role & RECEIVER)
|
||||
{
|
||||
timers["Decryption"].start();
|
||||
C.unpack(o);
|
||||
machine.sk.decrypt_any(product_share, C);
|
||||
res += product_share;
|
||||
timers["Decryption"].stop();
|
||||
}
|
||||
|
||||
memory_usage.update("multiplied ciphertext", C.report_size(CAPACITY));
|
||||
memory_usage.update("mask ciphertext", mask.report_size(CAPACITY));
|
||||
memory_usage.update("product shares", product_share.report_size(CAPACITY));
|
||||
@@ -75,9 +90,9 @@ void Multiplier<FD>::multiply_and_add(Plaintext_<FD>& res,
|
||||
|
||||
template <class FD>
|
||||
void Multiplier<FD>::multiply_alpha_and_add(Plaintext_<FD>& res,
|
||||
const Rq_Element& b)
|
||||
const Rq_Element& b, OT_ROLE role)
|
||||
{
|
||||
multiply_and_add(res, other_enc_alpha, b);
|
||||
multiply_and_add(res, other_enc_alpha, b, role);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "FHEOffline/SimpleEncCommit.h"
|
||||
#include "FHE/AddableVector.h"
|
||||
#include "Tools/MemoryUsage.h"
|
||||
#include "OT/BaseOT.h"
|
||||
|
||||
template <class FD>
|
||||
using PlaintextVector = AddableVector< Plaintext_<FD> >;
|
||||
@@ -41,8 +42,9 @@ public:
|
||||
void multiply_and_add(Plaintext_<FD>& res, const Ciphertext& C,
|
||||
const Plaintext_<FD>& b);
|
||||
void multiply_and_add(Plaintext_<FD>& res, const Ciphertext& C,
|
||||
const Rq_Element& b);
|
||||
void multiply_alpha_and_add(Plaintext_<FD>& res, const Rq_Element& b);
|
||||
const Rq_Element& b, OT_ROLE role = BOTH);
|
||||
void multiply_alpha_and_add(Plaintext_<FD>& res, const Rq_Element& b,
|
||||
OT_ROLE role = BOTH);
|
||||
int get_offset() { return P.get_offset(); }
|
||||
size_t report_size(ReportType type);
|
||||
void report_size(ReportType type, MemoryUsage& res);
|
||||
|
||||
@@ -6,20 +6,25 @@
|
||||
#include "FHEOffline/PairwiseGenerator.h"
|
||||
#include "FHEOffline/PairwiseMachine.h"
|
||||
#include "FHEOffline/Producer.h"
|
||||
#include "Protocols/SemiShare.h"
|
||||
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/SemiInput.hpp"
|
||||
#include "Protocols/ReplicatedInput.hpp"
|
||||
#include "Processor/Input.hpp"
|
||||
|
||||
template <class FD>
|
||||
PairwiseGenerator<FD>::PairwiseGenerator(int thread_num,
|
||||
PairwiseMachine& machine) :
|
||||
GeneratorBase(thread_num, machine.N),
|
||||
producer(machine.setup<FD>().FieldD, machine.N.my_num(),
|
||||
PairwiseMachine& machine, Player* player) :
|
||||
GeneratorBase(thread_num, machine.N, player),
|
||||
producer(machine.setup<FD>().FieldD, P.my_num(),
|
||||
thread_num, machine.output),
|
||||
EC(P, machine.other_pks, machine.setup<FD>().FieldD, timers, machine, *this),
|
||||
MC(machine.setup<FD>().alphai),
|
||||
C(machine.sec, machine.setup<FD>().params), volatile_memory(0),
|
||||
machine(machine), global_player(machine.N, (1LL << 28) + (thread_num << 16))
|
||||
machine(machine)
|
||||
{
|
||||
for (int i = 1; i < machine.N.num_players(); i++)
|
||||
for (int i = 1; i < P.num_players(); i++)
|
||||
multipliers.push_back(new Multiplier<FD>(i, *this));
|
||||
const FD& FieldD = machine.setup<FD>().FieldD;
|
||||
a.resize(machine.sec, FieldD);
|
||||
@@ -45,7 +50,6 @@ void PairwiseGenerator<FD>::run()
|
||||
{
|
||||
PRNG G;
|
||||
G.ReSeed();
|
||||
MAC_Check<typename FD::T> MC(machine.setup<FD>().alphai);
|
||||
|
||||
while (total < machine.nTriplesPerThread)
|
||||
{
|
||||
@@ -100,12 +104,53 @@ void PairwiseGenerator<FD>::run()
|
||||
timers["Checking"].stop();
|
||||
}
|
||||
|
||||
cout << "Could save " << 1e-9 * a.report_size(CAPACITY) << " GB" << endl;
|
||||
#ifdef FHE_MEMORY
|
||||
cerr << "Could save " << 1e-9 * a.report_size(CAPACITY) << " GB" << endl;
|
||||
#endif
|
||||
timers.insert(EC.timers.begin(), EC.timers.end());
|
||||
timers.insert(producer.timers.begin(), producer.timers.end());
|
||||
timers["Networking"] = P.timer;
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseGenerator<FD>::generate_inputs(int player)
|
||||
{
|
||||
bool mine = player == P.my_num();
|
||||
if (mine)
|
||||
{
|
||||
SeededPRNG G;
|
||||
b[0].randomize(G);
|
||||
b_mod_q.at(0).from_vec(b.at(0).get_poly());
|
||||
producer.macs[0].mul(machine.setup<FD>().alpha, b[0]);
|
||||
}
|
||||
else
|
||||
producer.macs[0].assign_zero();
|
||||
|
||||
for (auto m : multipliers)
|
||||
if (mine or P.get_player(m->get_offset()) == player)
|
||||
m->multiply_alpha_and_add(producer.macs[0], b_mod_q[0], mine ? SENDER : RECEIVER);
|
||||
|
||||
inputs.clear();
|
||||
Share<T> check_value;
|
||||
GlobalPRNG G(P);
|
||||
SemiInput<SemiShare<T>> input(0, P);
|
||||
input.reset_all(P);
|
||||
for (size_t i = 0; i < b[0].num_slots(); i++)
|
||||
{
|
||||
input.add_mine(b[0].element(i));
|
||||
}
|
||||
input.exchange();
|
||||
for (size_t i = 0; i < b[0].num_slots(); i++)
|
||||
{
|
||||
Share<T> share(input.finalize(player), producer.macs[0].element(i));
|
||||
inputs.push_back({share, b[0].element(i)});
|
||||
check_value += G.get<T>() * share;
|
||||
}
|
||||
inputs.pop_back();
|
||||
MC.POpen(check_value, P);
|
||||
MC.Check(P);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
size_t PairwiseGenerator<FD>::report_size(ReportType type)
|
||||
{
|
||||
@@ -124,7 +169,7 @@ size_t PairwiseGenerator<FD>::report_size(ReportType type)
|
||||
template <class FD>
|
||||
size_t PairwiseGenerator<FD>::report_sent()
|
||||
{
|
||||
return P.sent + global_player.sent;
|
||||
return P.sent;
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
|
||||
@@ -17,13 +17,17 @@ class PairwiseMachine;
|
||||
template <class FD>
|
||||
class PairwiseGenerator : public GeneratorBase
|
||||
{
|
||||
typedef typename FD::T T;
|
||||
|
||||
friend MultiEncCommit<FD>;
|
||||
template<class U> friend class CowGearPrep;
|
||||
|
||||
PlaintextVector<FD> a, b, c;
|
||||
AddableVector<Rq_Element> b_mod_q;
|
||||
vector<Multiplier<FD>*> multipliers;
|
||||
TripleProducer_<FD> producer;
|
||||
MultiEncCommit<FD> EC;
|
||||
MAC_Check<T> MC;
|
||||
|
||||
// temporary data
|
||||
AddableVector<Ciphertext> C;
|
||||
@@ -33,12 +37,15 @@ class PairwiseGenerator : public GeneratorBase
|
||||
|
||||
public:
|
||||
PairwiseMachine& machine;
|
||||
PlainPlayer global_player;
|
||||
|
||||
PairwiseGenerator(int thread_num, PairwiseMachine& machine);
|
||||
vector<InputTuple<Share<typename FD::T>>> inputs;
|
||||
|
||||
PairwiseGenerator(int thread_num, PairwiseMachine& machine, Player* player = 0);
|
||||
~PairwiseGenerator();
|
||||
|
||||
void run();
|
||||
void generate_inputs(int player);
|
||||
|
||||
size_t report_size(ReportType type);
|
||||
void report_size(ReportType type, MemoryUsage& res);
|
||||
size_t report_sent();
|
||||
|
||||
@@ -5,19 +5,31 @@
|
||||
|
||||
#include "FHEOffline/PairwiseMachine.h"
|
||||
#include "Tools/benchmarking.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
|
||||
PairwiseMachine::PairwiseMachine(Player& P) :
|
||||
P(P),
|
||||
other_pks(P.num_players(), {setup_p.params, 0}),
|
||||
pk(other_pks[P.my_num()]), sk(pk)
|
||||
{
|
||||
}
|
||||
|
||||
PairwiseMachine::PairwiseMachine(int argc, const char** argv) :
|
||||
MachineBase(argc, argv), P(N, 0xffff << 16),
|
||||
MachineBase(argc, argv), P(*new PlainPlayer(N, 0xffff << 16)),
|
||||
other_pks(N.num_players(), {setup_p.params, 0}),
|
||||
pk(other_pks[N.my_num()]), sk(pk)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void PairwiseMachine::init()
|
||||
{
|
||||
if (use_gf2n)
|
||||
{
|
||||
field_size = 40;
|
||||
gf2n::init_field(field_size);
|
||||
gf2n_short::init_field(field_size);
|
||||
setup_keys<P2Data>();
|
||||
}
|
||||
else
|
||||
@@ -52,8 +64,9 @@ PairwiseSetup<P2Data>& PairwiseMachine::setup()
|
||||
template <class FD>
|
||||
void PairwiseMachine::setup_keys()
|
||||
{
|
||||
auto& N = P;
|
||||
PairwiseSetup<FD>& s = setup<FD>();
|
||||
s.init(P, sec, field_size, extra_slack);
|
||||
s.init(P, drown_sec, field_size, extra_slack);
|
||||
if (output)
|
||||
write_mac_keys(PREP_DIR, P.my_num(), P.num_players(), setup_p.alphai,
|
||||
setup_2.alphai);
|
||||
@@ -70,9 +83,21 @@ void PairwiseMachine::setup_keys()
|
||||
for (int i = 0; i < N.num_players(); i++)
|
||||
if (i != N.my_num())
|
||||
other_pks[i].unpack(os[i]);
|
||||
set_mac_key(s.alphai);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void PairwiseMachine::set_mac_key(T alphai)
|
||||
{
|
||||
typedef typename T::FD FD;
|
||||
auto& N = P;
|
||||
PairwiseSetup<FD>& s = setup<FD>();
|
||||
s.alphai = alphai;
|
||||
for (size_t i = 0; i < s.alpha.num_slots(); i++)
|
||||
s.alpha.set_element(i, alphai);
|
||||
insecure("MAC key generation");
|
||||
Ciphertext enc_alpha = pk.encrypt(s.alpha);
|
||||
vector<octetStream> os;
|
||||
os.clear();
|
||||
os.resize(N.num_players());
|
||||
enc_alphas.resize(N.num_players(), pk);
|
||||
|
||||
@@ -15,18 +15,24 @@ class PairwiseMachine : public MachineBase
|
||||
public:
|
||||
PairwiseSetup<FFT_Data> setup_p;
|
||||
PairwiseSetup<P2Data> setup_2;
|
||||
PlainPlayer P;
|
||||
Player& P;
|
||||
|
||||
vector<FHE_PK> other_pks;
|
||||
FHE_PK& pk;
|
||||
FHE_SK sk;
|
||||
vector<Ciphertext> enc_alphas;
|
||||
|
||||
PairwiseMachine(Player& P);
|
||||
PairwiseMachine(int argc, const char** argv);
|
||||
|
||||
void init();
|
||||
|
||||
template <class FD>
|
||||
void setup_keys();
|
||||
|
||||
template <class T>
|
||||
void set_mac_key(T alphai);
|
||||
|
||||
template <class FD>
|
||||
PairwiseSetup<FD>& setup();
|
||||
};
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#include "FHE/NTL-Subs.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "FHEOffline/Proof.h"
|
||||
#include "FHEOffline/PairwiseMachine.h"
|
||||
#include "Tools/Commit.h"
|
||||
#include "Tools/Bundle.h"
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::init(const Player& P, int sec, int plaintext_length,
|
||||
int& extra_slack)
|
||||
{
|
||||
sec = max(sec, 40);
|
||||
cout << "Finding parameters for security " << sec << " and field size ~2^"
|
||||
<< plaintext_length << endl;
|
||||
PRNG G;
|
||||
@@ -44,5 +46,118 @@ void PairwiseSetup<FD>::init(const Player& P, int sec, int plaintext_length,
|
||||
alphai = alpha.element(0);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::secure_init(Player& P, PairwiseMachine& machine, int plaintext_length, int sec)
|
||||
{
|
||||
machine.sec = sec;
|
||||
sec = max(sec, 40);
|
||||
machine.drown_sec = sec;
|
||||
string filename = PREP_DIR "Params-" + FD::T::type_string() + "-"
|
||||
+ to_string(plaintext_length) + "-" + to_string(sec) + "-P"
|
||||
+ to_string(P.my_num());
|
||||
try
|
||||
{
|
||||
ifstream file(filename);
|
||||
octetStream os;
|
||||
os.input(file);
|
||||
os.get(machine.extra_slack);
|
||||
params.unpack(os);
|
||||
FieldD.unpack(os);
|
||||
FieldD.init_field();
|
||||
check(P, machine);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cout << "Finding parameters for security " << sec << " and field size ~2^"
|
||||
<< plaintext_length << endl;
|
||||
machine.extra_slack = generate_semi_setup(plaintext_length, sec, params, FieldD, true);
|
||||
check(P, machine);
|
||||
octetStream os;
|
||||
os.store(machine.extra_slack);
|
||||
params.pack(os);
|
||||
FieldD.pack(os);
|
||||
ofstream file(filename);
|
||||
os.output(file);
|
||||
}
|
||||
alpha = FieldD;
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::check(Player& P, PairwiseMachine& machine)
|
||||
{
|
||||
Bundle<octetStream> bundle(P);
|
||||
bundle.mine.store(machine.extra_slack);
|
||||
params.pack(bundle.mine);
|
||||
FieldD.hash(bundle.mine);
|
||||
P.Broadcast_Receive(bundle, true);
|
||||
for (auto& os : bundle)
|
||||
if (os != bundle.mine)
|
||||
throw runtime_error("mismatch of parameters among parties");
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::covert_key_generation(Player& P,
|
||||
PairwiseMachine& machine, int num_runs)
|
||||
{
|
||||
vector<SeededPRNG> G(num_runs);
|
||||
vector<AllCommitments> commits(num_runs, P);
|
||||
vector<FHE_KeyPair> my_keys(num_runs, {params, FieldD.get_prime()});
|
||||
Bundle<octetStream> pks(P);
|
||||
|
||||
for (int i = 0; i < num_runs; i++)
|
||||
{
|
||||
my_keys[i].generate(G[i]);
|
||||
my_keys[i].pk.pack(pks.mine);
|
||||
commits[i].commit({SEED_SIZE, G[i].get_seed()});
|
||||
}
|
||||
|
||||
P.Broadcast_Receive(pks);
|
||||
int challenge = GlobalPRNG(P).get_uint(num_runs);
|
||||
machine.sk = my_keys[challenge].sk;
|
||||
machine.pk = my_keys[challenge].pk;
|
||||
|
||||
for (int i = 0; i < num_runs; i++)
|
||||
if (i != challenge)
|
||||
commits[i].open({SEED_SIZE, G[i].get_seed()});
|
||||
|
||||
for (int i = 0; i < num_runs; i++)
|
||||
{
|
||||
for (int j = 0; j < P.num_players(); j++)
|
||||
if (j != P.my_num())
|
||||
{
|
||||
FHE_PK pk(params);
|
||||
pk.unpack(pks[j]);
|
||||
if (i == challenge)
|
||||
machine.other_pks[j] = pk;
|
||||
else
|
||||
{
|
||||
FHE_KeyPair pair(params, FieldD.get_prime());
|
||||
PRNG prng(commits[i].messages[j]);
|
||||
pair.generate(prng);
|
||||
if (pair.pk != pk)
|
||||
throw bad_keygen("covert pairwise key generation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::covert_mac_generation(Player& P,
|
||||
PairwiseMachine& machine, int num_runs)
|
||||
{
|
||||
vector<const FHE_PK*> pks;
|
||||
for (auto& pk : machine.other_pks)
|
||||
pks.push_back(&pk);
|
||||
covert_generation(alpha, machine.enc_alphas, pks, &P, num_runs, Diagonal);
|
||||
alphai = alpha.element(0);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::set_alphai(T alphai)
|
||||
{
|
||||
this->alphai = alphai;
|
||||
alpha.assign_constant(alphai);
|
||||
}
|
||||
|
||||
template class PairwiseSetup<FFT_Data>;
|
||||
template class PairwiseSetup<P2Data>;
|
||||
|
||||
@@ -10,9 +10,13 @@
|
||||
#include "FHE/Plaintext.h"
|
||||
#include "Networking/Player.h"
|
||||
|
||||
class PairwiseMachine;
|
||||
|
||||
template <class FD>
|
||||
class PairwiseSetup
|
||||
{
|
||||
typedef typename FD::T T;
|
||||
|
||||
public:
|
||||
FHE_Params params;
|
||||
FD FieldD;
|
||||
@@ -23,6 +27,13 @@ public:
|
||||
PairwiseSetup() : params(0), alpha(FieldD) {}
|
||||
|
||||
void init(const Player& P, int sec, int plaintext_length, int& extra_slack);
|
||||
|
||||
void secure_init(Player& P, PairwiseMachine& machine, int plaintext_length, int sec);
|
||||
void check(Player& P, PairwiseMachine& machine);
|
||||
void covert_key_generation(Player& P, PairwiseMachine& machine, int num_runs);
|
||||
void covert_mac_generation(Player& P, PairwiseMachine& machine, int num_runs);
|
||||
|
||||
void set_alphai(T alphai);
|
||||
};
|
||||
|
||||
#endif /* FHEOFFLINE_PAIRWISESETUP_H_ */
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FHE/P2Data.h"
|
||||
#include "FHE/FFT_Data.h"
|
||||
#include "Producer.h"
|
||||
#include "Sacrificing.h"
|
||||
#include "Reshare.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "FHEOffline/EncCommit.h"
|
||||
#include "FHEOffline/DistDecrypt.h"
|
||||
#include "FHEOffline/Sacrificing.h"
|
||||
#include "Math/Share.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Math/Setup.h"
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
*/
|
||||
|
||||
#include "Proof.h"
|
||||
#include "FHE/P2Data.h"
|
||||
#include "FHEOffline/EncCommit.h"
|
||||
|
||||
|
||||
double Proof::dist = 0;
|
||||
|
||||
bigint Proof::slack(int slack, int sec, int phim)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "Prover.h"
|
||||
|
||||
#include "FHE/P2Data.h"
|
||||
#include "Tools/random.h"
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
#include "FHEOffline/Reshare.h"
|
||||
#include "FHEOffline/DistDecrypt.h"
|
||||
#include "FHE/P2Data.h"
|
||||
#include "Tools/random.h"
|
||||
|
||||
template<class T,class FD,class S>
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FHE/P2Data.h"
|
||||
|
||||
#include "Sacrificing.h"
|
||||
#include "Producer.h"
|
||||
|
||||
#include "Auth/Subroutines.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
|
||||
// The number of sacrifices to amortize at one time
|
||||
#define amortize 512
|
||||
@@ -126,6 +128,8 @@ void Triple_Checking(const Player& P, MAC_Check<T>& MC, int nm,
|
||||
b1[i].output(outf,false);
|
||||
c1[i].output(outf,false);
|
||||
}
|
||||
else
|
||||
factory.triples.push_back({{a1[i], b1[i], c1[i]}});
|
||||
}
|
||||
|
||||
left_todo-=this_loop;
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
#define FHEOFFLINE_CHECKING_H_
|
||||
|
||||
#include "Networking/Player.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Math/gfp.h"
|
||||
|
||||
template <class T>
|
||||
class TripleSacriFactory
|
||||
{
|
||||
public:
|
||||
vector<array<T, 3>> triples;
|
||||
|
||||
virtual ~TripleSacriFactory() {}
|
||||
virtual void get(T& a, T& b, T& c) = 0;
|
||||
};
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "FHEOffline/SimpleMachine.h"
|
||||
#include "FHEOffline/Multiplier.h"
|
||||
#include "FHEOffline/PairwiseGenerator.h"
|
||||
#include "Auth/Subroutines.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Tools/Subroutines.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
|
||||
template<class T, class FD, class S>
|
||||
SimpleEncCommitBase<T, FD, S>::SimpleEncCommitBase(const MachineBase& machine) :
|
||||
@@ -151,8 +151,10 @@ size_t NonInteractiveProofSimpleEncCommit<FD>::create_more(octetStream& cipherte
|
||||
others_ciphertexts.resize(this->sec, pk.get_params());
|
||||
for (int i = 1; i < P.num_players(); i++)
|
||||
{
|
||||
cout << "Sending proof with " << 1e-9 * ciphertexts.get_length() << "+"
|
||||
#ifdef VERBOSE
|
||||
cerr << "Sending proof with " << 1e-9 * ciphertexts.get_length() << "+"
|
||||
<< 1e-9 * cleartexts.get_length() << " GB" << endl;
|
||||
#endif
|
||||
timers["Sending"].start();
|
||||
P.pass_around(ciphertexts);
|
||||
P.pass_around(cleartexts);
|
||||
@@ -160,7 +162,9 @@ size_t NonInteractiveProofSimpleEncCommit<FD>::create_more(octetStream& cipherte
|
||||
#ifndef LESS_ALLOC_MORE_MEM
|
||||
Verifier<FD,S> verifier(proof);
|
||||
#endif
|
||||
cout << "Checking proof of player " << i << endl;
|
||||
#ifdef VERBOSE
|
||||
cerr << "Checking proof of player " << i << endl;
|
||||
#endif
|
||||
timers["Verifying"].start();
|
||||
verifier.NIZKPoK(others_ciphertexts, ciphertexts,
|
||||
cleartexts, get_pk_for_verification(i), false, false);
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include <FHEOffline/SimpleGenerator.h>
|
||||
#include "FHEOffline/SimpleMachine.h"
|
||||
#include "FHEOffline/Sacrificing.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
|
||||
template <template <class> class T, class FD>
|
||||
SimpleGenerator<T,FD>::SimpleGenerator(const Names& N, const PartSetup<FD>& setup,
|
||||
|
||||
@@ -18,19 +18,29 @@ class MultiplicativeMachine;
|
||||
|
||||
class GeneratorBase
|
||||
{
|
||||
Player* player;
|
||||
|
||||
protected:
|
||||
int thread_num;
|
||||
|
||||
public:
|
||||
PlainPlayer P;
|
||||
Player& P;
|
||||
pthread_t thread;
|
||||
long long total;
|
||||
|
||||
map<string, Timer> timers;
|
||||
|
||||
GeneratorBase(int thread_num, const Names& N) :
|
||||
thread_num(thread_num), P(N, thread_num << 16), thread(0), total(0) {}
|
||||
virtual ~GeneratorBase() {}
|
||||
GeneratorBase(int thread_num, const Names& N, Player* player = 0) :
|
||||
player(player ? 0 : new PlainPlayer(N, thread_num << 16)),
|
||||
thread_num(thread_num),
|
||||
P(player ? *player : *this->player), thread(0), total(0)
|
||||
{
|
||||
}
|
||||
virtual ~GeneratorBase()
|
||||
{
|
||||
if (player)
|
||||
delete player;
|
||||
}
|
||||
virtual void run() = 0;
|
||||
virtual size_t report_size(ReportType type) = 0;
|
||||
virtual void report_size(ReportType type, MemoryUsage& res) = 0;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include "FHE/FHE_Keys.h"
|
||||
#include "Tools/time-func.h"
|
||||
#include "Tools/ezOptionParser.h"
|
||||
#include "Auth/MAC_Check.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/MAC_Check.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
void* run_generator(void* generator)
|
||||
{
|
||||
@@ -22,7 +22,9 @@ void* run_generator(void* generator)
|
||||
MachineBase::MachineBase() :
|
||||
throughput_loop_thread(0),portnum_base(0),
|
||||
data_type(DATA_TRIPLE),
|
||||
sec(0), field_size(0), extra_slack(0), produce_inputs(false)
|
||||
sec(0), drown_sec(0), field_size(0), extra_slack(0),
|
||||
produce_inputs(false),
|
||||
use_gf2n(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -84,6 +86,7 @@ void MachineBase::parse_options(int argc, const char** argv)
|
||||
opt.get("-h")->getString(hostname);
|
||||
opt.get("-pn")->getInt(portnum_base);
|
||||
opt.get("-s")->getInt(sec);
|
||||
drown_sec = max(40, sec);
|
||||
opt.get("-f")->getInt(field_size);
|
||||
use_gf2n = opt.isSet("-2");
|
||||
if (use_gf2n)
|
||||
@@ -196,7 +199,7 @@ void MultiplicativeMachine::generate_setup(int slack)
|
||||
{
|
||||
if (use_gf2n)
|
||||
{
|
||||
gf2n::init_field(field_size);
|
||||
gf2n_short::init_field(field_size);
|
||||
fake_keys<P2Data>(slack);
|
||||
}
|
||||
else
|
||||
@@ -213,12 +216,12 @@ void MultiplicativeMachine::fake_keys(int slack)
|
||||
PartSetup<FD>& part_setup = setup.part<FD>();
|
||||
if (P.my_num() == 0)
|
||||
{
|
||||
part_setup.generate_setup(N.num_players(), field_size, sec, slack, true);
|
||||
part_setup.generate_setup(N.num_players(), field_size, drown_sec, slack, true);
|
||||
if (output)
|
||||
{
|
||||
ofstream outf;
|
||||
bigint p = setup.FTD.get_prime();
|
||||
write_online_setup(outf, PREP_DIR, p != 0 ? p : 1, gf2n::degree());
|
||||
write_online_setup(outf, PREP_DIR, p != 0 ? p : 1, gf2n_short::degree());
|
||||
}
|
||||
|
||||
vector<PartSetup<FD> > setups;
|
||||
@@ -237,7 +240,7 @@ void MultiplicativeMachine::fake_keys(int slack)
|
||||
P.receive_player(0, os);
|
||||
}
|
||||
part_setup.unpack(os);
|
||||
part_setup.check(sec);
|
||||
part_setup.check(drown_sec);
|
||||
|
||||
if (output)
|
||||
write_mac_keys(PREP_DIR, N.my_num(), N.num_players(), setup.alphapi, setup.alpha2i);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
class MachineBase : public OfflineMachineBase
|
||||
{
|
||||
template<class T> friend class CowGearPrep;
|
||||
|
||||
protected:
|
||||
vector<GeneratorBase*> generators;
|
||||
string hostname;
|
||||
@@ -24,6 +26,7 @@ protected:
|
||||
|
||||
public:
|
||||
int sec;
|
||||
int drown_sec;
|
||||
int field_size;
|
||||
int extra_slack;
|
||||
bool produce_inputs;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
|
||||
#include "Math/gf2n.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/Share.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Math/Spdz2kShare.h"
|
||||
#include "Math/BrainShare.h"
|
||||
#include "Math/MaliciousRep3Share.h"
|
||||
#include "Math/SemiShare.h"
|
||||
#include "Auth/fake-stuff.h"
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
#include "Protocols/BrainShare.h"
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Protocols/SemiShare.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "GC/MaliciousRepSecret.h"
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
#include "Tools/ezOptionParser.h"
|
||||
#include "Tools/benchmarking.h"
|
||||
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
@@ -466,7 +467,7 @@ int main(int argc, const char** argv)
|
||||
throw runtime_error("not compiled for k=" + to_string(k) + " and s=" + to_string(s));
|
||||
}
|
||||
else
|
||||
return generate<sgfp>(opt);
|
||||
return generate<Share<gfp>>(opt);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
#include "MaliciousRepSecret.h"
|
||||
#include "Auth/ReplicatedMC.h"
|
||||
#include "Auth/MaliciousRepMC.h"
|
||||
#include "Protocols/ReplicatedMC.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
|
||||
#include "Instruction.hpp"
|
||||
#include "Machine.hpp"
|
||||
@@ -16,7 +16,9 @@
|
||||
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Auth/MaliciousRepMC.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/Replicated.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Auth/MaliciousRepMC.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "MaliciousRepThread.h"
|
||||
#include "Math/Setup.h"
|
||||
|
||||
#include "Auth/MaliciousRepMC.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
|
||||
namespace GC
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#ifndef GC_REPLICATEDPARTY_H_
|
||||
#define GC_REPLICATEDPARTY_H_
|
||||
|
||||
#include "Auth/ReplicatedMC.h"
|
||||
#include "Auth/MaliciousRepMC.h"
|
||||
#include "Protocols/ReplicatedMC.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "ReplicatedSecret.h"
|
||||
#include "Processor.h"
|
||||
#include "Program.h"
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
#include "ReplicatedSecret.h"
|
||||
#include "ReplicatedParty.h"
|
||||
#include "MaliciousRepSecret.h"
|
||||
#include "Auth/MaliciousRepMC.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
#include "MaliciousRepThread.h"
|
||||
#include "Thread.h"
|
||||
#include "square64.h"
|
||||
|
||||
#include "Math/Share.h"
|
||||
#include "Protocols/Share.h"
|
||||
|
||||
#include "Auth/ReplicatedMC.hpp"
|
||||
#include "Protocols/ReplicatedMC.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ using namespace std;
|
||||
#include "Math/FixedVec.h"
|
||||
#include "Math/BitVec.h"
|
||||
#include "Tools/SwitchableOutput.h"
|
||||
#include "Processor/Replicated.h"
|
||||
#include "Protocols/Replicated.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "GC/Memory.h"
|
||||
#include "GC/Access.h"
|
||||
|
||||
#include "Math/Share.h"
|
||||
#include "Math/gf2nlong.h"
|
||||
|
||||
#include "Processor/DummyProtocol.h"
|
||||
|
||||
@@ -56,11 +56,6 @@ public:
|
||||
Mask() : share(0) {}
|
||||
};
|
||||
|
||||
class SpdzShare : public Share<gf2n>
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
template<class T> class Processor;
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
*/
|
||||
|
||||
#include "Processor/config.h"
|
||||
#include "Protocols/Share.h"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
return spdz_main<sgfp, Share<gf2n>>(argc, argv, opt);
|
||||
return spdz_main<Share<gfp>, Share<gf2n>>(argc, argv, opt, false);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Processor/Machine.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Protocols/Share.h"
|
||||
#include "Tools/ezOptionParser.h"
|
||||
#include "Tools/Config.h"
|
||||
#include "Networking/Server.h"
|
||||
@@ -12,18 +13,19 @@
|
||||
using namespace std;
|
||||
|
||||
template<class T, class U>
|
||||
int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt, bool live_prep_default = true)
|
||||
{
|
||||
OnlineOptions online_opts(opt, argc, argv);
|
||||
OnlineOptions& online_opts = OnlineOptions::singleton;
|
||||
online_opts = {opt, argc, argv, 1000, live_prep_default};
|
||||
|
||||
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(
|
||||
to_string(gf2n::default_degree()).c_str(), // Default.
|
||||
to_string(U::clear::default_degree()).c_str(), // Default.
|
||||
0, // Required?
|
||||
1, // Number of args expected.
|
||||
0, // Delimiter if expecting multiple args.
|
||||
("Bit length of GF(2^n) field (default: " + to_string(gf2n::default_degree()) + ")").c_str(), // Help description.
|
||||
("Bit length of GF(2^n) field (default: " + to_string(U::clear::default_degree()) + ")").c_str(), // Help description.
|
||||
"-lg2", // Flag token.
|
||||
"--lg2" // Flag token.
|
||||
);
|
||||
@@ -120,15 +122,6 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
"-b", // Flag token.
|
||||
"--max-broadcast" // Flag token.
|
||||
);
|
||||
opt.add(
|
||||
"0", // Default.
|
||||
0, // Required?
|
||||
0, // Number of args expected.
|
||||
0, // Delimiter if expecting multiple args.
|
||||
"Use communications security between SPDZ players", // Help description.
|
||||
"-c", // Flag token.
|
||||
"--player-to-player-commsec" // Flag token.
|
||||
);
|
||||
opt.add(
|
||||
"", // Default.
|
||||
0, // Required?
|
||||
@@ -152,7 +145,6 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
|
||||
string memtype, hostname, ipFileName;
|
||||
int lg2, pnbase, opening_sum, max_broadcast;
|
||||
int p2pcommsec;
|
||||
int my_port;
|
||||
|
||||
online_opts.finalize(opt, argc, argv);
|
||||
@@ -163,7 +155,6 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
opt.get("--ip-file-name")->getString(ipFileName);
|
||||
opt.get("--opening-sum")->getInt(opening_sum);
|
||||
opt.get("--max-broadcast")->getInt(max_broadcast);
|
||||
opt.get("--player-to-player-commsec")->getInt(p2pcommsec);
|
||||
|
||||
ez::OptionGroup* mp_opt = opt.get("--my-port");
|
||||
if (mp_opt->isSet)
|
||||
@@ -174,16 +165,6 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
int mynum = online_opts.playerno;
|
||||
int playerno = online_opts.playerno;
|
||||
|
||||
CommsecKeysPackage *keys = NULL;
|
||||
if(p2pcommsec) {
|
||||
vector<public_signing_key> pubkeys;
|
||||
secret_signing_key mykey;
|
||||
public_signing_key mypublickey;
|
||||
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);
|
||||
}
|
||||
|
||||
Names playerNames;
|
||||
Server* server = 0;
|
||||
if (ipFileName.size() > 0) {
|
||||
@@ -206,7 +187,6 @@ int spdz_main(int argc, const char** argv, ez::ezOptionParser& opt)
|
||||
playerNames.init(playerno, pnbase, my_port, hostname.c_str());
|
||||
}
|
||||
}
|
||||
playerNames.set_keys(keys);
|
||||
|
||||
#ifndef INSECURE
|
||||
try
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Rep.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Math/MaliciousRep3Share.h"
|
||||
#include "Math/BrainShare.h"
|
||||
#include "Processor/BrainPrep.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/BrainPrep.hpp"
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Auth/MaliciousRepMC.hpp"
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<gfp>>* Preprocessing<Rep3Share<gfp>>::get_live_prep(
|
||||
SubProcessor<Rep3Share<gfp>>* proc, DataPositions& usage)
|
||||
{
|
||||
return new ReplicatedPrep<Rep3Share<gfp>>(proc, usage);
|
||||
}
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<gf2n>>* Preprocessing<Rep3Share<gf2n>>::get_live_prep(
|
||||
SubProcessor<Rep3Share<gf2n>>* proc, DataPositions& usage)
|
||||
{
|
||||
return new ReplicatedPrep<Rep3Share<gf2n>>(proc, usage);
|
||||
}
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<SignedZ2<64>>>* Preprocessing<Rep3Share<SignedZ2<64>>>::get_live_prep(
|
||||
SubProcessor<Rep3Share<SignedZ2<64>>>* proc, DataPositions& usage)
|
||||
{
|
||||
return new ReplicatedRingPrep<Rep3Share<SignedZ2<64>>>(proc, usage);
|
||||
}
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<SignedZ2<72>>>* Preprocessing<Rep3Share<SignedZ2<72>>>::get_live_prep(
|
||||
SubProcessor<Rep3Share<SignedZ2<72>>>* proc, DataPositions& usage)
|
||||
{
|
||||
return new ReplicatedRingPrep<Rep3Share<SignedZ2<72>>>(proc, usage);
|
||||
}
|
||||
|
||||
template class Machine<Rep3Share<SignedZ2<64>>, Rep3Share<gf2n>>;
|
||||
template class Machine<Rep3Share<SignedZ2<72>>, Rep3Share<gf2n>>;
|
||||
template class Machine<Rep3Share<gfp>, Rep3Share<gf2n>>;
|
||||
template class Machine<MaliciousRep3Share<gfp>, MaliciousRep3Share<gf2n>>;
|
||||
template class Machine<BrainShare<64, 40>, MaliciousRep3Share<gf2n>>;
|
||||
template class Machine<BrainShare<72, 40>, MaliciousRep3Share<gf2n>>;
|
||||
30
Machines/Rep.hpp
Normal file
30
Machines/Rep.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Rep.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Protocols/MalRepRingShare.h"
|
||||
#include "Protocols/BrainShare.h"
|
||||
#include "Protocols/BrainPrep.h"
|
||||
#include "Protocols/MalRepRingPrep.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Protocols/BrainPrep.hpp"
|
||||
#include "Protocols/MalRepRingPrep.hpp"
|
||||
#include "Protocols/MaliciousRepPrep.hpp"
|
||||
#include "Protocols/Spdz2kPrep.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
template<>
|
||||
Preprocessing<Rep3Share<gf2n>>* Preprocessing<Rep3Share<gf2n>>::get_live_prep(
|
||||
SubProcessor<Rep3Share<gf2n>>* proc, DataPositions& usage)
|
||||
{
|
||||
return new ReplicatedPrep<Rep3Share<gf2n>>(proc, usage);
|
||||
}
|
||||
@@ -1,15 +1,11 @@
|
||||
#include "Math/Spdz2kShare.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
#include "Processor/MascotPrep.hpp"
|
||||
#include "Processor/Spdz2kPrep.hpp"
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
|
||||
template class Machine<sgfp, Share<gf2n>>;
|
||||
|
||||
template class Machine<Spdz2kShare<64, 64>, Share<gf2n>>;
|
||||
template class Machine<Spdz2kShare<64, 48>, Share<gf2n>>;
|
||||
template class Machine<Share<gfp>, Share<gf2n>>;
|
||||
|
||||
18
Machines/SPDZ2k.hpp
Normal file
18
Machines/SPDZ2k.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDZ2k.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/Spdz2kShare.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
#include "Protocols/Spdz2kPrep.hpp"
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Semi.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Math/SemiShare.h"
|
||||
#include "Math/Semi2kShare.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "Auth/SemiMC.h"
|
||||
#include "Processor/SemiPrep.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/MascotPrep.hpp"
|
||||
#include "Processor/SemiPrep.hpp"
|
||||
#include "Processor/SemiInput.hpp"
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Auth/SemiMC.hpp"
|
||||
|
||||
template class Machine<SemiShare<gfp>, SemiShare<gf2n>>;
|
||||
template class Machine<Semi2kShare<64>, SemiShare<gf2n>>;
|
||||
template class Machine<Semi2kShare<72>, SemiShare<gf2n>>;
|
||||
23
Machines/Semi.hpp
Normal file
23
Machines/Semi.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Semi.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/SemiShare.h"
|
||||
#include "Protocols/Semi2kShare.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
#include "Protocols/SemiMC.h"
|
||||
#include "Protocols/SemiPrep.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
#include "Protocols/SemiPrep.hpp"
|
||||
#include "Protocols/SemiInput.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/SemiMC.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
@@ -4,22 +4,24 @@
|
||||
*/
|
||||
|
||||
#include <Machines/ShamirMachine.h>
|
||||
#include "Math/ShamirShare.h"
|
||||
#include "Math/MaliciousShamirShare.h"
|
||||
#include "Protocols/ShamirShare.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
#include "Math/gfp.h"
|
||||
#include "Math/gf2n.h"
|
||||
|
||||
#include "Processor/ReplicatedMachine.hpp"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/ShamirInput.hpp"
|
||||
#include "Processor/Shamir.hpp"
|
||||
#include "Auth/ShamirMC.hpp"
|
||||
#include "Auth/MaliciousShamirMC.hpp"
|
||||
#include "Auth/MAC_Check.hpp"
|
||||
#include "Auth/fake-stuff.hpp"
|
||||
#include "Protocols/ShamirInput.hpp"
|
||||
#include "Protocols/Shamir.hpp"
|
||||
#include "Protocols/MaliciousRepPrep.hpp"
|
||||
#include "Protocols/ShamirMC.hpp"
|
||||
#include "Protocols/MaliciousShamirMC.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
|
||||
ShamirMachine* ShamirMachine::singleton = 0;
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Math/BrainShare.h"
|
||||
#include "Math/MaliciousRep3Share.h"
|
||||
#include "Protocols/BrainShare.h"
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Processor/RingOptions.h"
|
||||
|
||||
#include "Processor/ReplicatedMachine.hpp"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
31
Machines/cowgear-party.cpp
Normal file
31
Machines/cowgear-party.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* cowgear-party.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/CowGearShare.h"
|
||||
#include "Protocols/CowGearPrep.h"
|
||||
#include "Protocols/CowGearOptions.h"
|
||||
|
||||
#include "FHE/FHE_Params.h"
|
||||
#include "FHE/FFT_Data.h"
|
||||
#include "FHE/NTL-Subs.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Protocols/MAC_Check.hpp"
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
|
||||
#include "Protocols/CowGearPrep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
CowGearOptions::singleton = CowGearOptions(opt, argc, argv);
|
||||
spdz_main<CowGearShare<gfp>, CowGearShare<gf2n_short>>(argc, argv, opt);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Machines/Rep.cpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Machines/ShamirMachine.cpp"
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
@@ -3,8 +3,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Math/MaliciousRep3Share.h"
|
||||
#include "Processor/ReplicatedMachine.hpp"
|
||||
#include "Protocols/MaliciousRep3Share.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
30
Machines/malicious-rep-ring-party.cpp
Normal file
30
Machines/malicious-rep-ring-party.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* mal-rep-ring-party.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/MalRepRingShare.h"
|
||||
#include "Protocols/MalRepRingOptions.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
MalRepRingOptions::singleton = MalRepRingOptions(opt, argc, argv);
|
||||
RingOptions opts(opt, argc, argv);
|
||||
switch (opts.R)
|
||||
{
|
||||
case 64:
|
||||
ReplicatedMachine<MalRepRingShare<64, 40>, MaliciousRep3Share<gf2n>>(
|
||||
argc, argv, opt);
|
||||
break;
|
||||
case 72:
|
||||
ReplicatedMachine<MalRepRingShare<72, 40>, MaliciousRep3Share<gf2n>>(
|
||||
argc, argv, opt);
|
||||
break;
|
||||
default:
|
||||
throw runtime_error(to_string(opts.R) + "-bit computation not implemented");
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "Machines/ShamirMachine.h"
|
||||
#include "Math/MaliciousShamirShare.h"
|
||||
#include "Protocols/MaliciousShamirShare.h"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
9
Machines/mascot-party.cpp
Normal file
9
Machines/mascot-party.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
#include "Player-Online.hpp"
|
||||
#include "Math/gfp.h"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
return spdz_main<Share<gfp>, Share<gf2n>>(argc, argv, opt);
|
||||
}
|
||||
16
Machines/ps-rep-field-party.cpp
Normal file
16
Machines/ps-rep-field-party.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* ps-rep-field-party.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/PostSacriRepFieldShare.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Protocols/PostSacrifice.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
ReplicatedMachine<PostSacriRepFieldShare<gfp>, PostSacriRepFieldShare<gf2n>>(
|
||||
argc, argv, opt);
|
||||
}
|
||||
30
Machines/ps-rep-ring-party.cpp
Normal file
30
Machines/ps-rep-ring-party.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* mal-rep-ring-party.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Protocols/PostSacriRepRingShare.h"
|
||||
#include "Protocols/PostSacriRepFieldShare.h"
|
||||
#include "Protocols/ReplicatedMachine.hpp"
|
||||
#include "Processor/RingOptions.h"
|
||||
#include "Machines/Rep.hpp"
|
||||
#include "Protocols/PostSacrifice.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
RingOptions opts(opt, argc, argv);
|
||||
switch (opts.R)
|
||||
{
|
||||
case 64:
|
||||
ReplicatedMachine<PostSacriRepRingShare<64, 40>, PostSacriRepFieldShare<gf2n>>(
|
||||
argc, argv, opt);
|
||||
break;
|
||||
case 72:
|
||||
ReplicatedMachine<PostSacriRepRingShare<72, 40>, PostSacriRepFieldShare<gf2n>>(
|
||||
argc, argv, opt);
|
||||
break;
|
||||
default:
|
||||
throw runtime_error(to_string(opts.R) + "-bit computation not implemented");
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Machines/Rep.cpp"
|
||||
#include "Machines/Rep.hpp"
|
||||
|
||||
#include "BMR/RealProgramParty.hpp"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user