mirror of
https://github.com/data61/MP-SPDZ.git
synced 2026-01-09 05:27:56 -05:00
Maintenance.
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Secret.hpp"
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
@@ -113,6 +112,7 @@ RealProgramParty<T>::RealProgramParty(int argc, const char** argv) :
|
||||
garble_processor.reset(program);
|
||||
this->processor.open_input_file(N.my_num(), 0);
|
||||
|
||||
T::bit_type::mac_key_type::init_field();
|
||||
GC::ShareThread<typename T::bit_type> share_thread(N, online_opts, *P, 0, usage);
|
||||
shared_proc = new SubProcessor<T>(dummy_proc, *MC, *prep, *P);
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void EvalRegister::store_clear_in_dynamic(GC::Memory<T>& mem,
|
||||
T& dest = mem[access.address];
|
||||
GC::Clear value = access.value;
|
||||
ProgramParty& party = ProgramParty::s();
|
||||
dest.assign(value.get(), party.get_id() - 1, party.get_mac_key().get());
|
||||
dest = T::constant(value.get(), party.get_id() - 1, party.get_mac_key().get());
|
||||
#ifdef DEBUG_DYNAMIC
|
||||
cout << "store clear " << dest.share << " " << dest.mac << " " << value << endl;
|
||||
#endif
|
||||
@@ -105,7 +105,7 @@ void EvalRegister::store(GC::Memory<U>& mem,
|
||||
U tmp;
|
||||
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());
|
||||
tmp = spdz_wire.mask + U::constant(ext, (int)party.get_id() - 1, party.get_mac_key());
|
||||
S.push_back(tmp);
|
||||
tmp *= gf2n_long(1) << i;
|
||||
dest += tmp;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,5 +1,14 @@
|
||||
The changelog explains changes pulled through from the private development repository. Bug fixes and small enhancements are committed between releases and not documented here.
|
||||
|
||||
## 0.2.2 (Jan 21, 2020)
|
||||
|
||||
- Infrastructure for random element generation
|
||||
- Programs generating as much preprocessing data as required by a particular high-level program
|
||||
- Smaller binaries
|
||||
- Cleaning up code
|
||||
- Removing unused virtual machine instructions
|
||||
- Fixed security bug: wrong MAC check in SPDZ2k input tuple generation
|
||||
|
||||
## 0.2.1 (Dec 11, 2020)
|
||||
|
||||
- Virtual machines automatically use the modulus used during compilation
|
||||
@@ -14,9 +23,9 @@ The changelog explains changes pulled through from the private development repos
|
||||
- Training and inference for multi-class classification
|
||||
- Local share conversion for semi-honest protocols based on additive secret sharing modulo a power of two
|
||||
- edaBit generation based on local share conversion
|
||||
- Optimize exponentation with local share conversion
|
||||
- Optimize exponentiation with local share conversion
|
||||
- Optimize Shamir pseudo-random secret sharing using a hyper-invertible matrix
|
||||
- Mathematical functions (exponentation, logarithm, square root, and trigonometric functions) with binary circuits
|
||||
- Mathematical functions (exponentiation, logarithm, square root, and trigonometric functions) with binary circuits
|
||||
- Direct construction of fixed-point values from any type, breaking `sfix(x)` where `x` is the integer representation of a fixed-point number. Use `sfix._new(x)` instead.
|
||||
- Optimized dot product for `sfix`
|
||||
- Matrix multiplication via operator overloading uses VM-optimized multiplication.
|
||||
@@ -70,7 +79,7 @@ The changelog explains changes pulled through from the private development repos
|
||||
- Mixed circuit computation with secret sharing
|
||||
- Binary computation for dishonest majority using secret sharing as in [FKOS15](https://eprint.iacr.org/2015/901)
|
||||
- Fixed security bug: insufficient OT correlation check in SPDZ2k
|
||||
- This version breaks bytecode compatibilty.
|
||||
- This version breaks bytecode compatibility.
|
||||
|
||||
## 0.1.3 (Nov 21, 2019)
|
||||
|
||||
@@ -133,7 +142,7 @@ The changelog explains changes pulled through from the private development repos
|
||||
## 0.0.4 (Oct 11, 2018)
|
||||
|
||||
- Added BMR, Yao's garbled circuits, and semi-honest 3-party replicated secret sharing for arithmetic and binary circuits.
|
||||
- Use inline assembly instead of MPIR for arithmetic modulo primes up length upt to 128 bit.
|
||||
- Use inline assembly instead of MPIR for arithmetic modulo primes up length up to 128 bit.
|
||||
- Added a secure multiplication instruction to the instruction set in order to accommodate protocols that don't use Beaver randomization.
|
||||
|
||||
## 0.0.3 (Mar 2, 2018)
|
||||
|
||||
@@ -483,10 +483,6 @@ class Merger:
|
||||
print("Processed dependency of %d/%d instructions at" % \
|
||||
(n, len(block.instructions)), time.asctime())
|
||||
|
||||
if len(open_nodes) > 1000 and self.block.parent.program.verbose:
|
||||
print("Basic block has %d %s instructions" %
|
||||
(len(open_nodes), merge_classes))
|
||||
|
||||
def merge_nodes(self, i, j):
|
||||
""" Merge node j into i, removing node j """
|
||||
G = self.G
|
||||
|
||||
@@ -288,18 +288,8 @@ def BitDecFieldRaw(a, k, m, kappa, bits_to_compute=None):
|
||||
c = types.cint()
|
||||
r = [types.sint() for i in range(m)]
|
||||
comparison.PRandM(r_dprime, r_prime, r, k, m, kappa)
|
||||
#assert(r_prime.value == sum(r[i].value*2**i for i in range(m)) % comparison.program.P)
|
||||
pow2 = two_power(k + kappa)
|
||||
asm_open(c, pow2 + two_power(k) + a - two_power(m)*r_dprime - r_prime)
|
||||
#rval = 2**m*r_dprime.value + r_prime.value
|
||||
#assert(rval % 2**m == r_prime.value)
|
||||
#assert(rval == (2**m*r_dprime.value + sum(r[i].value*2**i for i in range(m)) % comparison.program.P ))
|
||||
try:
|
||||
pass#assert(c.value == (2**(k + kappa) + 2**k + (a.value%2**k) - rval) % comparison.program.P)
|
||||
except AssertionError:
|
||||
print('BitDec assertion failed')
|
||||
print('a =', a.value)
|
||||
print('a mod 2^%d =' % k, (a.value % 2**k))
|
||||
res = r[0].bit_adder(r, list(r[0].bit_decompose_clear(c,m)))
|
||||
return res
|
||||
|
||||
@@ -328,7 +318,6 @@ def B2U(a, l, kappa):
|
||||
return B2U_from_Pow2(pow2a, l, kappa), pow2a
|
||||
|
||||
def B2U_from_Pow2(pow2a, l, kappa):
|
||||
#assert(pow2a.value == 2**a.value)
|
||||
r = [types.sint() for i in range(l)]
|
||||
t = types.sint()
|
||||
c = types.cint()
|
||||
@@ -354,8 +343,10 @@ def B2U_from_Pow2(pow2a, l, kappa):
|
||||
#print ' '.join(str(b.value) for b in y)
|
||||
return [types.sint.conv(1 - y[i]) for i in range(l)]
|
||||
|
||||
def Trunc(a, l, m, kappa, compute_modulo=False, signed=False):
|
||||
def Trunc(a, l, m, kappa=None, compute_modulo=False, signed=False):
|
||||
""" Oblivious truncation by secret m """
|
||||
prog = program.Program.prog
|
||||
kappa = kappa or prog.security
|
||||
if util.is_constant(m) and not compute_modulo:
|
||||
# cheaper
|
||||
res = type(a)(size=a.size)
|
||||
@@ -376,28 +367,22 @@ def Trunc(a, l, m, kappa, compute_modulo=False, signed=False):
|
||||
ci = [types.cint() for i in range(l)]
|
||||
d = types.sint()
|
||||
x, pow2m = B2U(m, l, kappa)
|
||||
#assert(pow2m.value == 2**m.value)
|
||||
#assert(sum(b.value for b in x) == m.value)
|
||||
for i in range(l):
|
||||
bit(r[i])
|
||||
t1 = two_power(i) * r[i]
|
||||
t2 = t1*x[i]
|
||||
r_prime += t2
|
||||
r_dprime += t1 - t2
|
||||
#assert(r_prime.value == (sum(2**i*x[i].value*r[i].value for i in range(l)) % comparison.program.P))
|
||||
if program.Program.prog.options.ring:
|
||||
n_shift = int(program.Program.prog.options.ring) - l
|
||||
c = ((a + r_dprime + r_prime) << n_shift).reveal() >> n_shift
|
||||
else:
|
||||
comparison.PRandInt(rk, kappa)
|
||||
r_dprime += two_power(l) * rk
|
||||
#assert(r_dprime.value == (2**l * rk.value + sum(2**i*(1 - x[i].value)*r[i].value for i in range(l)) % comparison.program.P))
|
||||
asm_open(c, a + r_dprime + r_prime)
|
||||
for i in range(1,l):
|
||||
ci[i] = c % two_power(i)
|
||||
#assert(ci[i].value == c.value % 2**i)
|
||||
c_dprime = sum(ci[i]*(x[i-1] - x[i]) for i in range(1,l))
|
||||
#assert(c_dprime.value == (sum(ci[i].value*(x[i-1].value - x[i].value) for i in range(1,l)) % comparison.program.P))
|
||||
lts(d, c_dprime, r_prime, l, kappa)
|
||||
if compute_modulo:
|
||||
b = c_dprime - r_prime + pow2m * d
|
||||
@@ -408,7 +393,6 @@ def Trunc(a, l, m, kappa, compute_modulo=False, signed=False):
|
||||
shifted = TruncInRing(to_shift, l, pow2m)
|
||||
else:
|
||||
pow2inv = Inv(pow2m)
|
||||
#assert(pow2inv.value * pow2m.value % comparison.program.P == 1)
|
||||
shifted = to_shift * pow2inv
|
||||
b = shifted - d
|
||||
return b
|
||||
|
||||
@@ -256,27 +256,6 @@ class gstmsi(base.WriteMemoryInstruction, base.IndirectMemoryInstruction):
|
||||
arg_format = ['sg','ci']
|
||||
direct = staticmethod(gstms)
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class protectmems(base.Instruction):
|
||||
r""" Protects secret memory range $[ci_i,ci_j)$. """
|
||||
code = base.opcodes['PROTECTMEMS']
|
||||
arg_format = ['ci','ci']
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class protectmemc(base.Instruction):
|
||||
r""" Protects clear memory range $[ci_i,ci_j)$. """
|
||||
code = base.opcodes['PROTECTMEMC']
|
||||
arg_format = ['ci','ci']
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class protectmemint(base.Instruction):
|
||||
r""" Protects integer memory range $[ci_i,ci_j)$. """
|
||||
code = base.opcodes['PROTECTMEMINT']
|
||||
arg_format = ['ci','ci']
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class movc(base.Instruction):
|
||||
@@ -1177,6 +1156,18 @@ class randoms(base.Instruction):
|
||||
arg_format = ['sw','int']
|
||||
field_type = 'modp'
|
||||
|
||||
@base.vectorize
|
||||
class randomfulls(base.Instruction):
|
||||
""" Store share(s) of a fresh secret random element in secret
|
||||
register (vectors).
|
||||
|
||||
:param: destination (sint)
|
||||
"""
|
||||
__slots__ = []
|
||||
code = base.opcodes['RANDOMFULLS']
|
||||
arg_format = ['sw']
|
||||
field_type = 'modp'
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class square(base.DataInstruction):
|
||||
@@ -1415,14 +1406,6 @@ class rawinput(base.RawInputInstruction, base.Mergeable):
|
||||
req_node.increment((self.field_type, 'input', player), \
|
||||
self.get_size())
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class print_mem(base.IOInstruction):
|
||||
r""" Print value in clear memory \verb|C[ci]| to stdout. """
|
||||
__slots__ = []
|
||||
code = base.opcodes['PRINTMEM']
|
||||
arg_format = ['c']
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
class print_reg(base.IOInstruction):
|
||||
@@ -1527,18 +1510,6 @@ class cond_print_str(base.IOInstruction):
|
||||
def __init__(self, cond, val):
|
||||
super(cond_print_str, self).__init__(cond, self.str_to_int(val))
|
||||
|
||||
@base.vectorize
|
||||
class print_char_regint(base.IOInstruction):
|
||||
r""" Print register $ci_i$ as a single character to stdout. """
|
||||
code = base.opcodes['PRINTCHRINT']
|
||||
arg_format = ['ci']
|
||||
|
||||
@base.vectorize
|
||||
class print_char4_regint(base.IOInstruction):
|
||||
r""" Print register $ci_i$ as a four character string to stdout. """
|
||||
code = base.opcodes['PRINTSTRINT']
|
||||
arg_format = ['ci']
|
||||
|
||||
@base.vectorize
|
||||
class pubinput(base.PublicFileIOInstruction):
|
||||
""" Store public input in clear integer register (vector).
|
||||
@@ -1717,6 +1688,11 @@ class startprivateoutput(base.Instruction):
|
||||
__slots__ = []
|
||||
code = base.opcodes['STARTPRIVATEOUTPUT']
|
||||
arg_format = ['sw','s','p']
|
||||
field_type = 'modp'
|
||||
|
||||
def add_usage(self, req_node):
|
||||
req_node.increment((self.field_type, 'input', self.args[2]), \
|
||||
self.get_size())
|
||||
|
||||
@base.gf2n
|
||||
@base.vectorize
|
||||
|
||||
@@ -112,6 +112,7 @@ opcodes = dict(
|
||||
EDABIT = 0x59,
|
||||
SEDABIT = 0x5A,
|
||||
RANDOMS = 0x5B,
|
||||
RANDOMFULLS = 0x5D,
|
||||
# Input
|
||||
INPUT = 0x60,
|
||||
INPUTFIX = 0xF0,
|
||||
|
||||
@@ -1511,7 +1511,7 @@ def break_point(name=''):
|
||||
# Fixed point ops
|
||||
|
||||
from math import ceil, log
|
||||
from .floatingpoint import PreOR, TruncPr, two_power, shift_two
|
||||
from .floatingpoint import PreOR, TruncPr, two_power
|
||||
|
||||
def approximate_reciprocal(divisor, k, f, theta):
|
||||
"""
|
||||
@@ -1599,7 +1599,6 @@ def sint_cint_division(a, b, k, f, kappa):
|
||||
B = absolute_b
|
||||
W = w0
|
||||
|
||||
|
||||
@for_range(1, theta)
|
||||
def block(i):
|
||||
A.link(TruncPr(A * W, 2*k, f, kappa))
|
||||
|
||||
@@ -393,7 +393,7 @@ def exp2_fx(a, zero_output=False):
|
||||
|
||||
@types.vectorize
|
||||
@instructions_base.sfix_cisc
|
||||
def log2_fx(x, use_division=False):
|
||||
def log2_fx(x, use_division=True):
|
||||
"""
|
||||
Returns the result of :math:`\log_2(x)` for any unbounded
|
||||
number. This is achieved by changing :py:obj:`x` into
|
||||
|
||||
@@ -614,12 +614,6 @@ class _clear(_register):
|
||||
__slots__ = []
|
||||
mov = staticmethod(movc)
|
||||
|
||||
@vectorized_classmethod
|
||||
@set_instruction_type
|
||||
def protect_memory(cls, start, end):
|
||||
program.curr_tape.start_new_basicblock(name='protect-memory')
|
||||
protectmemc(regint(start), regint(end))
|
||||
|
||||
@set_instruction_type
|
||||
@vectorize
|
||||
def load_other(self, val):
|
||||
@@ -1140,11 +1134,6 @@ class regint(_register, _int):
|
||||
instruction_type = 'modp'
|
||||
mov = staticmethod(movint)
|
||||
|
||||
@classmethod
|
||||
def protect_memory(cls, start, end):
|
||||
program.curr_tape.start_new_basicblock(name='protect-memory')
|
||||
protectmemint(regint(start), regint(end))
|
||||
|
||||
@vectorized_classmethod
|
||||
def load_mem(cls, address, mem_type=None):
|
||||
""" Load from memory by public address. """
|
||||
@@ -1530,12 +1519,6 @@ class _secret(_register):
|
||||
PreOR = staticmethod(lambda l: floatingpoint.PreORC(l))
|
||||
PreOp = staticmethod(lambda op, l: floatingpoint.PreOpL(op, l))
|
||||
|
||||
@vectorized_classmethod
|
||||
@set_instruction_type
|
||||
def protect_memory(cls, start, end):
|
||||
program.curr_tape.start_new_basicblock(name='protect-memory')
|
||||
protectmems(regint(start), regint(end))
|
||||
|
||||
@vectorized_classmethod
|
||||
@set_instruction_type
|
||||
def get_input_from(cls, player):
|
||||
@@ -1831,6 +1814,13 @@ class sint(_secret, _int):
|
||||
comparison.PRandInt(res, bits)
|
||||
return res
|
||||
|
||||
@vectorized_classmethod
|
||||
def get_random(cls):
|
||||
""" Secret random ring element according to security model. """
|
||||
res = sint()
|
||||
randomfulls(res)
|
||||
return res
|
||||
|
||||
@vectorized_classmethod
|
||||
def get_input_from(cls, player):
|
||||
""" Secret input.
|
||||
@@ -3197,6 +3187,8 @@ class _single(_number, _structure):
|
||||
__slots__ = ['v']
|
||||
kappa = None
|
||||
round_nearest = False
|
||||
""" Whether to round deterministically to nearest instead of
|
||||
probabilistically, e.g. after fixed-point multiplication. """
|
||||
|
||||
@classmethod
|
||||
def receive_from_client(cls, n, client_id, message_type=ClientMessageType.NoType):
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Processor/Data_Files.hpp"
|
||||
#include "Math/gfp.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -86,9 +86,7 @@ P256Element& P256Element::operator +=(const P256Element& other)
|
||||
|
||||
P256Element& P256Element::operator /=(const Scalar& other)
|
||||
{
|
||||
auto tmp = other;
|
||||
tmp.invert();
|
||||
*this = *this * tmp;
|
||||
*this = *this * other.invert();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ public:
|
||||
typedef void next;
|
||||
typedef void Square;
|
||||
|
||||
static const true_type invertible;
|
||||
|
||||
static int size() { return 0; }
|
||||
static string type_string() { return "P256"; }
|
||||
|
||||
@@ -55,10 +57,6 @@ public:
|
||||
|
||||
void assign_zero() { *this = 0; }
|
||||
bool is_zero() { return *this == 0; }
|
||||
void add(const P256Element& x, const P256Element& y) { *this = x + y; }
|
||||
void sub(const P256Element& x, const P256Element& y) { *this = x - y; }
|
||||
void mul(const P256Element& x, const Scalar& y) { *this = x * y; }
|
||||
void mul(const Scalar& x, const P256Element& y) { *this = y * x; }
|
||||
void add(octetStream& os) { *this += os.get<P256Element>(); }
|
||||
|
||||
void pack(octetStream& os) const;
|
||||
|
||||
@@ -59,7 +59,7 @@ void run(int argc, const char** argv)
|
||||
|
||||
OnlineOptions::singleton.batch_size = (1 + pShare::Protocol::uses_triples) * n_tuples;
|
||||
DataPositions usage;
|
||||
auto& prep = *Preprocessing<pShare>::get_live_prep(0, usage);
|
||||
typename pShare::TriplePrep prep(0, usage);
|
||||
typename pShare::MAC_Check MCp;
|
||||
ArithmeticProcessor _({}, 0);
|
||||
SubProcessor<pShare> proc(_, MCp, prep, P);
|
||||
@@ -69,6 +69,4 @@ void run(int argc, const char** argv)
|
||||
preprocessing(tuples, n_tuples, sk, proc, opts);
|
||||
// check(tuples, sk, {}, P);
|
||||
sign_benchmark(tuples, sk, MCp, P, opts, prep_mul ? 0 : &proc);
|
||||
|
||||
delete &prep;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ void run(int argc, const char** argv)
|
||||
OnlineOptions::singleton.batch_size = 1;
|
||||
typename pShare::Direct_MC MCp(keyp);
|
||||
ArithmeticProcessor _({}, 0);
|
||||
typename pShare::LivePrep sk_prep(0, usage);
|
||||
typename pShare::TriplePrep sk_prep(0, usage);
|
||||
GC::ShareThread<typename pShare::bit_type> thread(N,
|
||||
OnlineOptions::singleton, P, {}, usage);
|
||||
SubProcessor<pShare> sk_proc(_, MCp, sk_prep, P);
|
||||
@@ -119,7 +119,7 @@ void run(int argc, const char** argv)
|
||||
(P.comm_stats - stats).print(true);
|
||||
|
||||
OnlineOptions::singleton.batch_size = (1 + pShare::Protocol::uses_triples) * n_tuples;
|
||||
typename pShare::LivePrep prep(0, usage);
|
||||
typename pShare::TriplePrep prep(0, usage);
|
||||
prep.params.correlation_check &= not opt.isSet("-U");
|
||||
prep.params.fewer_rounds = opt.isSet("-A");
|
||||
prep.params.fiat_shamir = opt.isSet("-H");
|
||||
|
||||
@@ -121,8 +121,7 @@ void check(vector<EcTuple<T>>& tuples, T<P256Element::Scalar> sk,
|
||||
for (auto& tuple : tuples)
|
||||
{
|
||||
auto inv_k = MC.open(tuple.a, P);
|
||||
auto k = inv_k;
|
||||
k.invert();
|
||||
auto k = inv_k.invert();
|
||||
assert(open_sk * inv_k == MC.open(tuple.b, P));
|
||||
assert(tuple.R == k);
|
||||
}
|
||||
|
||||
@@ -103,11 +103,9 @@ EcSignature sign(const unsigned char* message, size_t length, P256Element::Scala
|
||||
{
|
||||
EcSignature signature;
|
||||
auto k = SeededPRNG().get<P256Element::Scalar>();
|
||||
auto inv_k = k;
|
||||
inv_k.invert();
|
||||
signature.R = k;
|
||||
auto rx = signature.R.x();
|
||||
signature.s = inv_k * (hash_to_scalar(message, length) + rx * sk);
|
||||
signature.s = k.invert() * (hash_to_scalar(message, length) + rx * sk);
|
||||
return signature;
|
||||
}
|
||||
|
||||
@@ -119,8 +117,7 @@ void check(EcSignature signature, const unsigned char* message, size_t length,
|
||||
timer.start();
|
||||
signature.s.check();
|
||||
signature.R.check();
|
||||
P256Element::Scalar w;
|
||||
w.invert(signature.s);
|
||||
auto w = signature.s.invert();
|
||||
auto u1 = hash_to_scalar(message, length) * w;
|
||||
auto u2 = signature.R.x() * w;
|
||||
assert(P256Element(u1) + pk * u2 == signature.R);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Ciphertext.h"
|
||||
#include "PPData.h"
|
||||
#include "P2Data.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include "Math/modp.hpp"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "FHE_Params.h"
|
||||
#include "FHE/Ring_Element.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
|
||||
void FHE_Params::set(const Ring& R,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "FHE/Matrix.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include "Math/modp.hpp"
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ void P2Data::backward(vector<gf2n_short>& ans,const vector<poly_type>& a) const
|
||||
int ii = i * n + n - 1 - j;
|
||||
y ^= (Ai[ii] & bv).parity();
|
||||
}
|
||||
ans[i].assign(y);
|
||||
ans[i] = (y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void Plaintext<gfp,PPData,bigint>::from_poly() const
|
||||
if (type!=Polynomial) { return; }
|
||||
vector<modp> aa((*Field_Data).phi_m());
|
||||
for (unsigned int i=0; i<aa.size(); i++)
|
||||
{ to_modp(aa[i],b[i],(*Field_Data).prData); }
|
||||
{ to_modp(aa[i], bigint::tmp = b[i], (*Field_Data).prData); }
|
||||
(*Field_Data).to_eval(aa);
|
||||
a.resize(n_slots);
|
||||
for (unsigned int i=0; i<aa.size(); i++)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "Ring.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
void Ring::pack(octetStream& o) const
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "FHE/Ring_Element.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "FHE/FFT.h"
|
||||
|
||||
#include "Math/modp.hpp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Rq_Element.h"
|
||||
#include "FHE_Keys.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include "Math/modp.hpp"
|
||||
|
||||
|
||||
@@ -50,9 +50,10 @@ void PartSetup<FD>::generate_setup(int n_parties, int plaintext_length, int sec,
|
||||
|
||||
template <class FD>
|
||||
void PartSetup<FD>::fake(vector<FHE_SK>& sks, vector<T>& alphais,
|
||||
int nplayers, bool distributed)
|
||||
int nplayers, bool distributed, bool check_security)
|
||||
{
|
||||
insecure("global key generation");
|
||||
if (check_security)
|
||||
insecure("global key generation");
|
||||
if (distributed)
|
||||
cout << "Faking distributed key generation" << endl;
|
||||
else
|
||||
@@ -91,11 +92,11 @@ void PartSetup<FD>::fake(vector<FHE_SK>& sks, vector<T>& alphais,
|
||||
|
||||
template <class FD>
|
||||
void PartSetup<FD>::fake(vector<PartSetup<FD> >& setups, int nplayers,
|
||||
bool distributed)
|
||||
bool distributed, bool check_security)
|
||||
{
|
||||
vector<FHE_SK> sks;
|
||||
vector<T> alphais;
|
||||
fake(sks, alphais, nplayers, distributed);
|
||||
fake(sks, alphais, nplayers, distributed, check_security);
|
||||
setups.clear();
|
||||
setups.resize(nplayers, *this);
|
||||
for (int i = 0; i < nplayers; i++)
|
||||
|
||||
@@ -38,8 +38,10 @@ public:
|
||||
void generate_setup(int n_parties, int plaintext_length, int sec, int slack,
|
||||
bool round_up);
|
||||
|
||||
void fake(vector<FHE_SK>& sks, vector<T>& alphais, int nplayers, bool distributed = true);
|
||||
void fake(vector<PartSetup<FD> >& setups, int nplayers, bool distributed = true);
|
||||
void fake(vector<FHE_SK>& sks, vector<T>& alphais, int nplayers,
|
||||
bool distributed = true, bool check_security = true);
|
||||
void fake(vector<PartSetup<FD> >& setups, int nplayers,
|
||||
bool distributed = true, bool check_security = true);
|
||||
void insecure_debug_keys(vector<PartSetup<FD> >& setups, int nplayers, bool simple_pk);
|
||||
|
||||
void pack(octetStream& os);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
#include "Tools/Subroutines.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/random.h"
|
||||
|
||||
#include "EncCommit.h"
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "Tools/Bundle.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Protocols/mac_key.hpp"
|
||||
|
||||
template <class FD>
|
||||
void PairwiseSetup<FD>::init(const Player& P, int sec, int plaintext_length,
|
||||
int& extra_slack)
|
||||
@@ -21,7 +24,6 @@ void PairwiseSetup<FD>::init(const Player& P, int sec, int plaintext_length,
|
||||
<< plaintext_length << endl;
|
||||
PRNG G;
|
||||
G.ReSeed();
|
||||
dirname = PREP_DIR;
|
||||
|
||||
octetStream o;
|
||||
if (P.my_num() == 0)
|
||||
@@ -43,8 +45,8 @@ void PairwiseSetup<FD>::init(const Player& P, int sec, int plaintext_length,
|
||||
}
|
||||
|
||||
alpha = FieldD;
|
||||
alpha.randomize(G, Diagonal);
|
||||
alphai = alpha.element(0);
|
||||
alphai = read_or_generate_mac_key<Share<T>>(P);
|
||||
alpha.assign_constant(alphai);
|
||||
}
|
||||
|
||||
template <class FD>
|
||||
|
||||
@@ -27,7 +27,6 @@ public:
|
||||
FD FieldD;
|
||||
typename FD::T alphai;
|
||||
Plaintext_<FD> alpha;
|
||||
string dirname;
|
||||
|
||||
static string name()
|
||||
{
|
||||
|
||||
@@ -277,9 +277,7 @@ void InverseProducer<FD>::get(Share<T>& a, Share<T>& b)
|
||||
}
|
||||
|
||||
TupleProducer<FD>::get(a, b);
|
||||
T ab_inv;
|
||||
ab_inv.invert(ab.element(i - 1));
|
||||
b.mul(b,ab_inv);
|
||||
b /= ab.element(i - 1);
|
||||
}
|
||||
|
||||
void gfpBitProducer::get(Share<gfp>& a)
|
||||
@@ -394,9 +392,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk,
|
||||
else
|
||||
{
|
||||
marks[i] = 0;
|
||||
gfp temp;
|
||||
temp.invert(s.element(i).sqrRoot());
|
||||
s.set_element(i, temp);
|
||||
s.set_element(i, s.element(i).sqrRoot().invert());
|
||||
}
|
||||
}
|
||||
Ciphertext cv(params);
|
||||
@@ -416,7 +412,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk,
|
||||
gfp two_inv, zero;
|
||||
two_inv = bigint((dd.f.get_field().get_prime() + 1) / 2);
|
||||
zero.assign_zero();
|
||||
one.assign_one();
|
||||
auto shared_one = Share<gfp>::constant(1, P.my_num(), alphai);
|
||||
bits.clear();
|
||||
for (unsigned int i = 0; i < vi.num_slots(); i++)
|
||||
{
|
||||
@@ -425,7 +421,7 @@ void gfpBitProducer::run(const Player& P, const FHE_PK& pk,
|
||||
a.set_share(vi.element(i));
|
||||
a.set_mac(gam_vi.element(i));
|
||||
// Form (1/2)*a+1
|
||||
a.add(a, one, P.my_num(), alphai);
|
||||
a += shared_one;
|
||||
a.mul(a, two_inv);
|
||||
bits.push_back(a);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ void Triple_Checking(const Player& P, MAC_Check<T>& MC, int nm,
|
||||
temp.mul(b2[i],PO[2*i]);
|
||||
Sh_Tau[i].sub(Sh_Tau[i],temp);
|
||||
te = (PO[2*i] * PO[2*i+1]);
|
||||
Sh_Tau[i].sub(Sh_Tau[i],te,P.my_num(),MC.get_alphai());
|
||||
Sh_Tau[i].sub(Sh_Tau[i], Share<T>::constant(te,P.my_num(),MC.get_alphai()));
|
||||
}
|
||||
MC.POpen_Begin(Tau,Sh_Tau,P);
|
||||
MC.POpen_End(Tau,Sh_Tau,P);
|
||||
@@ -148,9 +148,11 @@ void Inverse_Checking(const Player& P, MAC_Check<T>& MC, int nr,
|
||||
MC.POpen_Begin(PO,Sh_PO,P);
|
||||
MC.POpen_End(PO,Sh_PO,P);
|
||||
|
||||
auto t_shared = Share<T>::constant(t, P.my_num(), MC.get_alphai());
|
||||
|
||||
for (int i=0; i<this_loop; i++)
|
||||
{
|
||||
Sh_Tau[i].sub(c2[i],t,P.my_num(),MC.get_alphai());
|
||||
Sh_Tau[i].sub(c2[i],t_shared);
|
||||
temp.mul(a2[i],PO[2*i+1]);
|
||||
Sh_Tau[i].add(Sh_Tau[i],temp);
|
||||
temp.mul(b1[i],PO[2*i]);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "Protocols/fake-stuff.h"
|
||||
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/mac_key.hpp"
|
||||
#include "Protocols/Share.hpp"
|
||||
#include "Math/modp.hpp"
|
||||
|
||||
void* run_generator(void* generator)
|
||||
@@ -238,6 +240,13 @@ void MultiplicativeMachine::fake_keys(int slack)
|
||||
part_setup.unpack(os);
|
||||
part_setup.check(drown_sec);
|
||||
|
||||
part_setup.alphai = read_or_generate_mac_key<Share<typename FD::T>>(P);
|
||||
Plaintext_<FD> m(part_setup.FieldD);
|
||||
m.assign_constant(part_setup.alphai);
|
||||
vector<Ciphertext> C({part_setup.pk.encrypt(m)});
|
||||
TreeSum<Ciphertext>().run(C, P);
|
||||
part_setup.calpha = C[0];
|
||||
|
||||
if (output)
|
||||
part_setup.output(N);
|
||||
}
|
||||
|
||||
38
GC/BitPrepFiles.h
Normal file
38
GC/BitPrepFiles.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* BitPrepFiles.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_BITPREPFILES_H_
|
||||
#define GC_BITPREPFILES_H_
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
#include "ShiftableTripleBuffer.h"
|
||||
#include "Processor/Data_Files.h"
|
||||
|
||||
template<class T>
|
||||
class BitPrepFiles : public ShiftableTripleBuffer<T>, public Sub_Data_Files<T>
|
||||
{
|
||||
public:
|
||||
BitPrepFiles(const Names& N, const string& prep_data_dir,
|
||||
DataPositions& usage, int thread_num = -1) :
|
||||
Sub_Data_Files<T>(N, prep_data_dir, usage, thread_num)
|
||||
{
|
||||
}
|
||||
|
||||
array<T, 3> get_triple_no_count(int n_bits)
|
||||
{
|
||||
return ShiftableTripleBuffer<T>::get_triple_no_count(n_bits);
|
||||
}
|
||||
|
||||
void get(Dtype type, T* data)
|
||||
{
|
||||
Sub_Data_Files<T>::get(type, data);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* GC_BITPREPFILES_H_ */
|
||||
@@ -29,6 +29,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CcdPrep(SubProcessor<T>*, DataPositions& usage) :
|
||||
CcdPrep(usage, ShareThread<T>::s())
|
||||
{
|
||||
}
|
||||
|
||||
~CcdPrep()
|
||||
{
|
||||
if (part_proc)
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CcdSecret(const super& other) :
|
||||
CcdSecret(const typename super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ public:
|
||||
|
||||
static const int default_length = 1;
|
||||
|
||||
static DataFieldType field_type()
|
||||
{
|
||||
return DATA_GF2;
|
||||
}
|
||||
|
||||
static string name()
|
||||
{
|
||||
return "CCD";
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
|
||||
void reveal(int n_bits, Clear& x) { (void) n_bits; x = a; }
|
||||
|
||||
void invert(FakeSecret) { throw not_implemented(); }
|
||||
FakeSecret invert() const { throw not_implemented(); }
|
||||
|
||||
void input(istream&, bool) { throw not_implemented(); }
|
||||
|
||||
|
||||
@@ -22,14 +22,12 @@
|
||||
namespace GC
|
||||
{
|
||||
|
||||
inline
|
||||
Instruction::Instruction() :
|
||||
BaseInstruction()
|
||||
{
|
||||
size = 1;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Instruction::get_offline_data_usage(int& usage)
|
||||
{
|
||||
switch (opcode)
|
||||
@@ -42,7 +40,6 @@ bool Instruction::get_offline_data_usage(int& usage)
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned Instruction::get_mem(RegType reg_type) const
|
||||
{
|
||||
unsigned m = n + 1;
|
||||
@@ -73,7 +70,6 @@ unsigned Instruction::get_mem(RegType reg_type) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline
|
||||
void Instruction::parse(istream& s, int pos)
|
||||
{
|
||||
BaseInstruction::parse(s, pos);
|
||||
@@ -30,10 +30,6 @@ public:
|
||||
|
||||
// Returns the memory size used if applicable and known
|
||||
unsigned get_mem(RegType reg_type) const;
|
||||
|
||||
// Execute this instruction
|
||||
template<class T, class U>
|
||||
bool execute(Processor<T>& processor, U& dynamic_memory) const;
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -27,32 +27,6 @@ inline bool fallback_code(const Instruction& instruction, Processor<T>& processo
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
MAYBE_INLINE bool Instruction::execute(Processor<T>& processor,
|
||||
U& dynamic_memory) const
|
||||
{
|
||||
#ifdef DEBUG_OPS
|
||||
cout << typeid(T).name() << " ";
|
||||
cout << "pc " << processor.PC << " op " << hex << showbase << opcode << " "
|
||||
<< dec << noshowbase << r[0];
|
||||
if (CommonParty::singleton)
|
||||
cout << ", " << CommonParty::s().get_reg_size() << " regs ";
|
||||
if (ProgramParty::singleton)
|
||||
ProgramParty::s().print_input_size<T>();
|
||||
cout << endl;
|
||||
#endif
|
||||
const Instruction& instruction = *this;
|
||||
auto& Ci = processor.I;
|
||||
switch (opcode)
|
||||
{
|
||||
#define X(NAME, CODE) case NAME: CODE; return true;
|
||||
INSTRUCTIONS
|
||||
#undef X
|
||||
default:
|
||||
return fallback_code(*this, processor);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
#endif /* GC_INSTRUCTION_INLINE_H_ */
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Machine.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MaliciousRepSecret.h"
|
||||
#include "Protocols/ReplicatedMC.h"
|
||||
#include "Protocols/MaliciousRepMC.h"
|
||||
|
||||
#include "Instruction.hpp"
|
||||
#include "Machine.hpp"
|
||||
#include "Processor.hpp"
|
||||
#include "Program.hpp"
|
||||
#include "Thread.hpp"
|
||||
#include "ThreadMaster.hpp"
|
||||
|
||||
#include "Processor/Machine.hpp"
|
||||
#include "Processor/Instruction.hpp"
|
||||
#include "Protocols/MaliciousRepMC.hpp"
|
||||
#include "Protocols/MAC_Check_Base.hpp"
|
||||
#include "Protocols/Beaver.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
#define GC_MACHINE(T) \
|
||||
template class Instruction<T>; \
|
||||
template class Machine<T>; \
|
||||
template class Processor<T>; \
|
||||
template class Program<T>; \
|
||||
template class Thread<T>; \
|
||||
template class ThreadMaster<T>; \
|
||||
|
||||
} /* namespace GC */
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
Machine();
|
||||
~Machine();
|
||||
|
||||
void load_schedule(string progname);
|
||||
void load_program(string threadname, string filename);
|
||||
void load_schedule(const string& progname);
|
||||
void load_program(const string& threadname, const string& filename);
|
||||
|
||||
template<class U>
|
||||
void reset(const U& program);
|
||||
|
||||
@@ -35,7 +35,7 @@ Machine<T>::~Machine()
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Machine<T>::load_program(string threadname, string filename)
|
||||
void Machine<T>::load_program(const string& threadname, const string& filename)
|
||||
{
|
||||
(void)threadname;
|
||||
progs.push_back({});
|
||||
@@ -44,7 +44,7 @@ void Machine<T>::load_program(string threadname, string filename)
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Machine<T>::load_schedule(string progname)
|
||||
void Machine<T>::load_schedule(const string& progname)
|
||||
{
|
||||
BaseMachine::load_schedule(progname);
|
||||
print_compiler();
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
MaliciousCcdSecret(const super& other) :
|
||||
MaliciousCcdSecret(const typename super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ public:
|
||||
|
||||
static const int default_length = 1;
|
||||
|
||||
static DataFieldType field_type()
|
||||
{
|
||||
return DATA_GF2;
|
||||
}
|
||||
|
||||
static string name()
|
||||
{
|
||||
return "Malicious CCD";
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <typeinfo>
|
||||
using namespace std;
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Clear.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
16
GC/NoShare.h
16
GC/NoShare.h
@@ -24,6 +24,7 @@ class NoValue : public ValueInterface
|
||||
{
|
||||
public:
|
||||
typedef NoValue Scalar;
|
||||
typedef NoValue next;
|
||||
|
||||
const static int n_bits = 0;
|
||||
const static int MAX_N_BITS = 0;
|
||||
@@ -48,6 +49,11 @@ public:
|
||||
return "no";
|
||||
}
|
||||
|
||||
static string type_short()
|
||||
{
|
||||
return "no";
|
||||
}
|
||||
|
||||
static void fail()
|
||||
{
|
||||
throw runtime_error("VM does not support binary circuits");
|
||||
@@ -70,6 +76,11 @@ public:
|
||||
void randomize(PRNG&) { fail(); }
|
||||
|
||||
void invert() { fail(); }
|
||||
|
||||
void mask(int) { fail(); }
|
||||
|
||||
void input(istream&, bool) { fail(); }
|
||||
void output(ostream&, bool) { fail(); }
|
||||
};
|
||||
|
||||
inline ostream& operator<<(ostream& o, NoValue)
|
||||
@@ -176,12 +187,17 @@ public:
|
||||
NoShare operator&(int) const { fail(); return {}; }
|
||||
NoShare operator>>(int) const { fail(); return {}; }
|
||||
|
||||
NoShare& operator+=(const NoShare&) { fail(); return *this; }
|
||||
|
||||
NoShare lsb() const { fail(); return {}; }
|
||||
NoShare get_bit(int) const { fail(); return {}; }
|
||||
|
||||
void invert(int, NoShare) { fail(); }
|
||||
|
||||
NoShare mask(int) const { fail(); return {}; }
|
||||
|
||||
void input(istream&, bool) { fail(); }
|
||||
void output(ostream&, bool) { fail(); }
|
||||
};
|
||||
|
||||
} /* namespace GC */
|
||||
|
||||
@@ -27,7 +27,7 @@ void PersonalPrep<T>::buffer_personal_triples()
|
||||
template<class T>
|
||||
void PersonalPrep<T>::buffer_personal_triples(size_t batch_size, ThreadQueues* queues)
|
||||
{
|
||||
ShuffleSacrifice<T> sacri;
|
||||
TripleShuffleSacrifice<T> sacri;
|
||||
batch_size = max(batch_size, (size_t)sacri.minimum_n_outputs()) + sacri.C;
|
||||
vector<array<T, 3>> triples(batch_size);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ using namespace std;
|
||||
|
||||
#include "GC/Machine.hpp"
|
||||
#include "Processor/ProcessorBase.hpp"
|
||||
#include "Math/bigint.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
#define GC_PROGRAM_HPP_
|
||||
|
||||
#include <GC/Program.h>
|
||||
#include "Instruction_inline.h"
|
||||
#include "instructions.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Tools/callgrind.h"
|
||||
|
||||
#include "Instruction.hpp"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
@@ -82,7 +82,6 @@ void Program::parse(istream& s)
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
__attribute__((flatten))
|
||||
BreakType Program::execute(Processor<T>& Proc, U& dynamic_memory,
|
||||
int PC) const
|
||||
{
|
||||
@@ -95,6 +94,8 @@ BreakType Program::execute(Processor<T>& Proc, U& dynamic_memory,
|
||||
unsigned int size = p.size();
|
||||
size_t time = Proc.time;
|
||||
Proc.complexity = 0;
|
||||
auto& Ci = Proc.I;
|
||||
auto& processor = Proc;
|
||||
do
|
||||
{
|
||||
#ifdef DEBUG_EXE
|
||||
@@ -109,7 +110,15 @@ BreakType Program::execute(Processor<T>& Proc, U& dynamic_memory,
|
||||
#ifdef COUNT_INSTRUCTIONS
|
||||
Proc.stats[p[Proc.PC].get_opcode()]++;
|
||||
#endif
|
||||
p[Proc.PC++].execute(Proc, dynamic_memory);
|
||||
auto& instruction = p[Proc.PC++];
|
||||
switch (instruction.get_opcode())
|
||||
{
|
||||
#define X(NAME, CODE) case NAME: CODE; break;
|
||||
INSTRUCTIONS
|
||||
#undef X
|
||||
default:
|
||||
fallback_code(instruction, processor);
|
||||
}
|
||||
time++;
|
||||
#ifdef DEBUG_COMPLEXITY
|
||||
cout << "complexity at " << time << ": " << Proc.complexity << endl;
|
||||
|
||||
@@ -41,9 +41,9 @@ public:
|
||||
BufferPrep<T>::get(type, data);
|
||||
}
|
||||
|
||||
array<T, 3> get_triple(int n_bits)
|
||||
array<T, 3> get_triple_no_count(int n_bits)
|
||||
{
|
||||
return ShiftableTripleBuffer<T>::get_triple(n_bits);
|
||||
return ShiftableTripleBuffer<T>::get_triple_no_count(n_bits);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -127,8 +127,8 @@ public:
|
||||
void load_clear(int n, const Integer& x);
|
||||
void operator=(const Integer& x) { load_clear(default_length, x); }
|
||||
|
||||
Secret<T> operator<<(int i);
|
||||
Secret<T> operator>>(int i);
|
||||
Secret<T> operator<<(int i) const;
|
||||
Secret<T> operator>>(int i) const;
|
||||
|
||||
template<class U>
|
||||
void bitcom(Memory<U>& S, const vector<int>& regs);
|
||||
|
||||
@@ -183,7 +183,7 @@ void Secret<T>::load(vector<ReadAccess <V> >& accesses, const U& mem)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Secret<T> Secret<T>::operator<<(int i)
|
||||
Secret<T> Secret<T>::operator<<(int i) const
|
||||
{
|
||||
Secret<T> res;
|
||||
for (int j = 0; j < i; j++)
|
||||
@@ -194,7 +194,7 @@ Secret<T> Secret<T>::operator<<(int i)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Secret<T> Secret<T>::operator>>(int i)
|
||||
Secret<T> Secret<T>::operator>>(int i) const
|
||||
{
|
||||
Secret<T> res;
|
||||
res.registers.insert(res.registers.end(), registers.begin() + i, registers.end());
|
||||
@@ -219,10 +219,8 @@ template <class U>
|
||||
void Secret<T>::bitdec(Memory<U>& S, const vector<int>& regs) const
|
||||
{
|
||||
if (regs.size() > registers.size())
|
||||
throw out_of_range(
|
||||
"not enough bits for bit decomposition: "
|
||||
+ to_string(regs.size()) + " > "
|
||||
+ to_string(registers.size()));
|
||||
throw overflow("not enough bits for bit decomposition", regs.size(),
|
||||
registers.size());
|
||||
for (unsigned int i = 0; i < regs.size(); i++)
|
||||
{
|
||||
Secret& secret = S[regs[i]];
|
||||
|
||||
@@ -43,9 +43,9 @@ public:
|
||||
BufferPrep<SemiSecret>::get(type, data);
|
||||
}
|
||||
|
||||
array<SemiSecret, 3> get_triple(int n_bits)
|
||||
array<SemiSecret, 3> get_triple_no_count(int n_bits)
|
||||
{
|
||||
return ShiftableTripleBuffer<SemiSecret>::get_triple(n_bits);
|
||||
return ShiftableTripleBuffer<SemiSecret>::get_triple_no_count(n_bits);
|
||||
}
|
||||
|
||||
void buffer_personal_triples(vector<array<SemiSecret, 3>>&, size_t, size_t)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <GC/ShareThread.h>
|
||||
#include "GC/ShareParty.h"
|
||||
#include "BitPrepFiles.h"
|
||||
#include "Math/Setup.h"
|
||||
|
||||
#include "Processor/Data_Files.hpp"
|
||||
@@ -27,7 +28,7 @@ ShareThread<T>::ShareThread(const Names& N, OnlineOptions& opts, DataPositions&
|
||||
opts.live_prep ?
|
||||
*static_cast<Preprocessing<T>*>(new typename T::LivePrep(
|
||||
usage, *this)) :
|
||||
*static_cast<Preprocessing<T>*>(new Sub_Data_Files<T>(N,
|
||||
*static_cast<Preprocessing<T>*>(new BitPrepFiles<T>(N,
|
||||
get_prep_sub_dir<T>(PREP_DIR, N.num_players()), usage)))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ public:
|
||||
|
||||
virtual ~ShiftableTripleBuffer() {}
|
||||
|
||||
array<T, 3> get_triple(int n_bits)
|
||||
array<T, 3> get_triple_no_count(int n_bits)
|
||||
{
|
||||
int max_n_bits = T::N_BITS;
|
||||
int max_n_bits = T::default_length;
|
||||
assert(n_bits <= max_n_bits);
|
||||
assert(n_bits > 0);
|
||||
array<T, 3> res;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Program.h"
|
||||
|
||||
#include "Networking/CryptoPlayer.h"
|
||||
#include "Processor/Processor.h"
|
||||
|
||||
#include "Processor.hpp"
|
||||
|
||||
|
||||
@@ -98,17 +98,8 @@ void ThreadMaster<T>::run()
|
||||
|
||||
delete P;
|
||||
|
||||
for (auto it : exe_stats)
|
||||
switch (it.first)
|
||||
{
|
||||
#define X(NAME, CODE) case NAME: cerr << it.second << " " #NAME << endl; break;
|
||||
INSTRUCTIONS
|
||||
#undef X
|
||||
}
|
||||
|
||||
for (auto it = stats.begin(); it != stats.end(); it++)
|
||||
if (it->second.data > 0)
|
||||
cerr << it->first << " " << 1e-6 * it->second.data << " MB" << endl;
|
||||
exe_stats.print();
|
||||
stats.print();
|
||||
|
||||
cerr << "Time = " << timer.elapsed() << " seconds" << endl;
|
||||
cerr << "Data sent = " << data_sent * 1e-6 << " MB" << endl;
|
||||
|
||||
@@ -21,6 +21,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
TinierPrep(SubProcessor<T>*, DataPositions& usage) :
|
||||
TinierPrep(usage, ShareThread<T>::s())
|
||||
{
|
||||
}
|
||||
|
||||
void buffer_inputs(int player)
|
||||
{
|
||||
this->buffer_inputs_(player, this->triple_generator);
|
||||
|
||||
@@ -35,6 +35,7 @@ class TinierSharePrep : public PersonalPrep<T>
|
||||
public:
|
||||
TinierSharePrep(DataPositions& usage, int input_player =
|
||||
PersonalPrep<T>::SECURE);
|
||||
TinierSharePrep(SubProcessor<T>*, DataPositions& usage);
|
||||
~TinierSharePrep();
|
||||
|
||||
void set_protocol(typename T::Protocol& protocol);
|
||||
|
||||
@@ -22,6 +22,12 @@ TinierSharePrep<T>::TinierSharePrep(DataPositions& usage, int input_player) :
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
TinierSharePrep<T>::TinierSharePrep(SubProcessor<T>*, DataPositions& usage) :
|
||||
TinierSharePrep(usage)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
TinierSharePrep<T>::~TinierSharePrep()
|
||||
{
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
#include "OT/MascotParams.h"
|
||||
#include "Protocols/Beaver.h"
|
||||
#include "Protocols/ReplicatedPrep.h"
|
||||
#include "Protocols/RandomPrep.h"
|
||||
|
||||
namespace GC
|
||||
{
|
||||
|
||||
template<class T>
|
||||
class TinyPrep : public BufferPrep<T>, public RandomPrep<typename T::part_type::super>
|
||||
class TinyPrep : public BufferPrep<T>
|
||||
{
|
||||
protected:
|
||||
ShareThread<T>& thread;
|
||||
@@ -43,9 +42,7 @@ public:
|
||||
|
||||
void buffer_inputs_(int player, typename T::InputGenerator* input_generator);
|
||||
|
||||
typename T::part_type::super get_random();
|
||||
|
||||
array<T, 3> get_triple(int n_bits);
|
||||
array<T, 3> get_triple_no_count(int n_bits);
|
||||
|
||||
size_t data_sent();
|
||||
};
|
||||
|
||||
@@ -68,7 +68,6 @@ void TinyOnlyPrep<T>::set_protocol(Beaver<T>& protocol)
|
||||
OnlineOptions::singleton.batch_size, 1, this->params,
|
||||
this->thread.MC->get_alphai(), &protocol.P);
|
||||
input_generator->multi_threaded = false;
|
||||
this->thread.MC->get_part_MC().set_prep(*this);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
@@ -78,7 +77,7 @@ void TinyPrep<T>::buffer_triples()
|
||||
assert(triple_generator != 0);
|
||||
params.generateBits = false;
|
||||
vector<array<typename T::check_type, 3>> triples;
|
||||
ShuffleSacrifice<typename T::check_type> sacrifice;
|
||||
TripleShuffleSacrifice<typename T::check_type> sacrifice;
|
||||
size_t required;
|
||||
if (amplify)
|
||||
required = sacrifice.minimum_n_inputs_with_combining();
|
||||
@@ -169,15 +168,7 @@ void TinyPrep<T>::buffer_inputs_(int player, typename T::InputGenerator* input_g
|
||||
}
|
||||
|
||||
template<class T>
|
||||
typename T::part_type::super GC::TinyPrep<T>::get_random()
|
||||
{
|
||||
T tmp;
|
||||
this->get_one(DATA_BIT, tmp);
|
||||
return tmp.get_reg(0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
array<T, 3> TinyPrep<T>::get_triple(int n_bits)
|
||||
array<T, 3> TinyPrep<T>::get_triple_no_count(int n_bits)
|
||||
{
|
||||
assert(n_bits > 0);
|
||||
while ((unsigned)n_bits > triple_buffer.size())
|
||||
|
||||
@@ -60,9 +60,10 @@ public:
|
||||
return part_type::size() * default_length;
|
||||
}
|
||||
|
||||
template<class U>
|
||||
static void generate_mac_key(mac_key_type&, const U&)
|
||||
static void read_or_generate_mac_key(string directory, const Player& P,
|
||||
mac_key_type& key)
|
||||
{
|
||||
T::read_or_generate_mac_key(directory, P, key);
|
||||
}
|
||||
|
||||
template<class U>
|
||||
@@ -218,7 +219,7 @@ public:
|
||||
TinySecret()
|
||||
{
|
||||
}
|
||||
TinySecret(const super& other) :
|
||||
TinySecret(const typename super::super& other) :
|
||||
super(other)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ public:
|
||||
part_input.reset_all(P);
|
||||
}
|
||||
|
||||
VectorInput(SubProcessor<T>& proc, typename T::MAC_Check&) :
|
||||
VectorInput(proc.MC, proc.DataF, proc.P)
|
||||
{
|
||||
}
|
||||
|
||||
void reset(int player)
|
||||
{
|
||||
part_input.reset(player);
|
||||
|
||||
@@ -33,7 +33,7 @@ typename T::clear VectorProtocol<T>::prepare_mul(const T& x,
|
||||
const T& y, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
part_protocol.prepare_mul(x.get_reg(i), y.get_reg(i));
|
||||
part_protocol.prepare_mul(x.get_reg(i), y.get_reg(i), 1);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ T VectorProtocol<T>::finalize_mul(int n)
|
||||
T res;
|
||||
res.resize_regs(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
res.get_reg(i) = part_protocol.finalize_mul();
|
||||
res.get_reg(i) = part_protocol.finalize_mul(1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
CSIRO Open Source Software Licence Agreement (variation of the BSD / MIT License)
|
||||
Copyright (c) 2020, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230.
|
||||
Copyright (c) 2021, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230.
|
||||
All rights reserved. CSIRO is willing to grant you a licence to this MP-SPDZ sofware on the following terms, except where otherwise indicated for third party material.
|
||||
Redistribution and use of this software in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Networking/Player.h"
|
||||
#include "OT/OTExtension.h"
|
||||
#include "OT/OTExtensionWithMatrix.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/time-func.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
#include "Math/Setup.h"
|
||||
#include "Protocols/fake-stuff.h"
|
||||
#include "Math/BitVec.h"
|
||||
#include "GC/TinierSecret.h"
|
||||
|
||||
#include "Protocols/fake-stuff.hpp"
|
||||
#include "Protocols/MascotPrep.hpp"
|
||||
#include "Math/Z2k.hpp"
|
||||
#include "Math/gfp.hpp"
|
||||
#include "OT/NPartyTripleGenerator.hpp"
|
||||
|
||||
20
Machines/cowgear-offline.cpp
Normal file
20
Machines/cowgear-offline.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* cowgear-offline.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SPDZ.hpp"
|
||||
#include "Math/gfp.hpp"
|
||||
#include "Protocols/CowGearShare.h"
|
||||
#include "Protocols/CowGearOptions.h"
|
||||
#include "Protocols/CowGearPrep.hpp"
|
||||
#include "Processor/FieldMachine.hpp"
|
||||
#include "Processor/OfflineMachine.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
CowGearOptions::singleton = CowGearOptions(opt, argc, argv);
|
||||
DishonestMajorityFieldMachine<CowGearShare, CowGearShare, gf2n_short,
|
||||
OfflineMachine<DishonestMajorityMachine>>(argc, argv, opt);
|
||||
}
|
||||
18
Machines/mal-shamir-offline.cpp
Normal file
18
Machines/mal-shamir-offline.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* mal-shamir-offline.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ShamirMachine.hpp"
|
||||
#include "MalRep.hpp"
|
||||
#include "Processor/OfflineMachine.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
auto& opts = ShamirOptions::singleton;
|
||||
ez::ezOptionParser opt;
|
||||
opts = {opt, argc, argv};
|
||||
HonestMajorityFieldMachine<MaliciousShamirShare,
|
||||
OfflineMachine<HonestMajorityMachine>>(argc, argv, opt,
|
||||
opts.nparties);
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/MaliciousRepSecret.h"
|
||||
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
|
||||
18
Machines/mascot-offline.cpp
Normal file
18
Machines/mascot-offline.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* mascot-offline.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
#include "GC/TinierSecret.h"
|
||||
|
||||
#include "SPDZ.hpp"
|
||||
#include "Math/gfp.hpp"
|
||||
#include "Processor/FieldMachine.hpp"
|
||||
#include "Processor/OfflineMachine.hpp"
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
ez::ezOptionParser opt;
|
||||
DishonestMajorityFieldMachine<Share, Share, gf2n,
|
||||
OfflineMachine<DishonestMajorityMachine>>(argc, argv, opt);
|
||||
}
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Thread.hpp"
|
||||
#include "GC/ThreadMaster.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "GC/ShareParty.hpp"
|
||||
#include "GC/ShareSecret.hpp"
|
||||
#include "GC/Instruction.hpp"
|
||||
#include "GC/Machine.hpp"
|
||||
#include "GC/Processor.hpp"
|
||||
#include "GC/Program.hpp"
|
||||
|
||||
19
Makefile
19
Makefile
@@ -21,7 +21,7 @@ COMMON = $(MATH) $(TOOLS) $(NETWORK) GC/square64.o Processor/OnlineOptions.o Pro
|
||||
COMPLETE = $(COMMON) $(PROCESSOR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(GC) $(OT)
|
||||
YAO = $(patsubst %.cpp,%.o,$(wildcard Yao/*.cpp)) $(OT) BMR/Key.o
|
||||
BMR = $(patsubst %.cpp,%.o,$(wildcard BMR/*.cpp BMR/network/*.cpp))
|
||||
VM = $(PROCESSOR) $(COMMON) GC/square64.o OT/OTTripleSetup.o OT/BaseOT.o $(LIBSIMPLEOT)
|
||||
VM = $(PROCESSOR) $(COMMON) GC/square64.o GC/Instruction.o OT/OTTripleSetup.o OT/BaseOT.o $(LIBSIMPLEOT)
|
||||
|
||||
|
||||
LIB = libSPDZ.a
|
||||
@@ -29,14 +29,14 @@ LIBRELEASE = librelease.a
|
||||
LIBSIMPLEOT = SimpleOT/libsimpleot.a
|
||||
|
||||
# used for dependency generation
|
||||
OBJS = $(BMR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(YAO) $(COMPLETE) $(patsubst %.cpp,%.o,$(wildcard Machines/*.cpp))
|
||||
OBJS = $(BMR) $(FHEOFFLINE) $(TINYOTOFFLINE) $(YAO) $(COMPLETE) $(patsubst %.cpp,%.o,$(wildcard Machines/*.cpp Utils/*.cpp))
|
||||
DEPS := $(wildcard */*.d */*/*.d)
|
||||
|
||||
# never delete
|
||||
.SECONDARY: $(OBJS)
|
||||
|
||||
|
||||
all: arithmetic binary gen_input online offline externalIO bmr doc
|
||||
all: arithmetic binary gen_input online offline externalIO bmr ecdsa doc
|
||||
|
||||
.PHONY: doc
|
||||
doc:
|
||||
@@ -59,7 +59,7 @@ include $(wildcard *.d static/*.d)
|
||||
|
||||
online: Fake-Offline.x Server.x Player-Online.x Check-Offline.x emulate.x
|
||||
|
||||
offline: $(OT_EXE) Check-Offline.x
|
||||
offline: $(OT_EXE) Check-Offline.x mascot-offline.x cowgear-offline.x mal-shamir-offline.x
|
||||
|
||||
gen_input: gen_input_f2n.x gen_input_fp.x
|
||||
|
||||
@@ -100,7 +100,7 @@ shamir: shamir-party.x malicious-shamir-party.x galois-degree.x
|
||||
|
||||
sy: sy-rep-field-party.x sy-rep-ring-party.x sy-shamir-party.x
|
||||
|
||||
ecdsa: $(patsubst ECDSA/%.cpp,%.x,$(wildcard ECDSA/*-ecdsa-party.cpp))
|
||||
ecdsa: $(patsubst ECDSA/%.cpp,%.x,$(wildcard ECDSA/*-ecdsa-party.cpp)) Fake-ECDSA.x
|
||||
ecdsa-static: static-dir $(patsubst ECDSA/%.cpp,static/%.x,$(wildcard ECDSA/*-ecdsa-party.cpp))
|
||||
|
||||
$(LIBRELEASE): Protocols/MalRepRingOptions.o $(PROCESSOR) $(COMMON) $(OT) $(GC)
|
||||
@@ -115,9 +115,9 @@ static/%.x: ECDSA/%.o ECDSA/P256Element.o $(VM) $(OT) $(LIBSIMPLEOT)
|
||||
static-dir:
|
||||
@ mkdir static 2> /dev/null; true
|
||||
|
||||
static-release: static-dir $(patsubst Machines/%.cpp, static/%.x, $(wildcard Machines/*-party.cpp))
|
||||
static-release: static-dir $(patsubst Machines/%.cpp, static/%.x, $(wildcard Machines/*-party.cpp)) static/emulate.x
|
||||
|
||||
Fake-ECDSA.x: ECDSA/Fake-ECDSA.cpp ECDSA/P256Element.o $(COMMON)
|
||||
Fake-ECDSA.x: ECDSA/Fake-ECDSA.cpp ECDSA/P256Element.o $(COMMON) Processor/PrepBase.o
|
||||
$(CXX) -o $@ $^ $(CFLAGS) $(LDLIBS) $(ECLIB)
|
||||
|
||||
Check-Offline.x: $(PROCESSOR)
|
||||
@@ -127,7 +127,7 @@ ot.x: $(OT) $(COMMON) Machines/OText_main.o Machines/OTMachine.o $(LIBSIMPLEOT)
|
||||
|
||||
ot-offline.x: $(OT) $(LIBSIMPLEOT) Machines/TripleMachine.o
|
||||
|
||||
gc-emulate.x: $(PROCESSOR) GC/FakeSecret.o GC/square64.o
|
||||
gc-emulate.x: $(VM) GC/FakeSecret.o GC/square64.o
|
||||
|
||||
bmr-%.x: $(BMR) $(VM) Machines/bmr-%.cpp $(LIBSIMPLEOT)
|
||||
$(CXX) -o $@ $(CFLAGS) $^ $(BOOST) $(LDLIBS)
|
||||
@@ -205,6 +205,9 @@ emulate.x: GC/FakeSecret.o
|
||||
semi-bmr-party.x: GC/SemiPrep.o GC/SemiSecret.o $(OT)
|
||||
real-bmr-party.x: $(OT)
|
||||
paper-example.x: $(VM) $(OT) $(FHEOFFLINE)
|
||||
mascot-offline.x: $(VM) $(OT)
|
||||
cowgear-offline.x: $(OT) $(FHEOFFLINE)
|
||||
Fake-Offline.x: $(VM)
|
||||
static/rep-bmr-party.x: $(BMR)
|
||||
static/mal-rep-bmr-party.x: $(BMR)
|
||||
static/shamir-bmr-party.x: $(BMR)
|
||||
|
||||
@@ -24,6 +24,9 @@ public:
|
||||
|
||||
static const int n_bits = sizeof(T) * 8;
|
||||
|
||||
static const false_type invertible;
|
||||
static const true_type characteristic_two;
|
||||
|
||||
static char type_char() { return 'B'; }
|
||||
static string type_short() { return "B"; }
|
||||
static DataFieldType field_type() { return DATA_GF2; }
|
||||
@@ -73,4 +76,9 @@ public:
|
||||
|
||||
typedef BitVec_<long> BitVec;
|
||||
|
||||
template<class T>
|
||||
const false_type BitVec_<T>::invertible;
|
||||
template<class T>
|
||||
const true_type BitVec_<T>::characteristic_two;
|
||||
|
||||
#endif /* MATH_BITVEC_H_ */
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
FixedVec<T, L>(const T& other = 0)
|
||||
FixedVec<T, L>(const T& other = {})
|
||||
{
|
||||
for (auto& x : v)
|
||||
x = other;
|
||||
@@ -128,12 +128,7 @@ public:
|
||||
void mul(const FixedVec<T, L>& x, const FixedVec<T, L>& y)
|
||||
{
|
||||
for (int i = 0; i < L; i++)
|
||||
v[i].mul(x.v[i], y.v[i]);
|
||||
}
|
||||
|
||||
void add(const FixedVec<T, L>& x)
|
||||
{
|
||||
add(*this, x);
|
||||
v[i] = (x.v[i] * y.v[i]);
|
||||
}
|
||||
|
||||
void add(octetStream& os)
|
||||
@@ -225,7 +220,7 @@ public:
|
||||
|
||||
FixedVec<T, L>& operator+=(const FixedVec<T, L>& other)
|
||||
{
|
||||
add(other);
|
||||
add(*this, other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,9 +150,6 @@ class Integer : public IntBase<long>
|
||||
|
||||
void mul(const Integer& x) { *this = *this * x; }
|
||||
|
||||
void invert() { throw runtime_error("cannot invert integer"); }
|
||||
void invert(const Integer& _) { (void)_; invert(); }
|
||||
|
||||
void AND(const Integer& x, const Integer& y) { *this = x & y; }
|
||||
void OR(const Integer& x, const Integer& y) { *this = x | y; }
|
||||
void XOR(const Integer& x, const Integer& y) { *this = x ^ y; }
|
||||
|
||||
@@ -140,3 +140,24 @@ void write_online_setup(string dirname, const bigint& p)
|
||||
if (!outf.good())
|
||||
throw file_error("cannot write to " + ss.str());
|
||||
}
|
||||
|
||||
void check_setup(string dir, bigint pr)
|
||||
{
|
||||
bigint p;
|
||||
string filename = dir + "Params-Data";
|
||||
ifstream(filename) >> p;
|
||||
if (p != pr)
|
||||
throw runtime_error("wrong modulus in " + dir);
|
||||
}
|
||||
|
||||
string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod,
|
||||
const string& type_short)
|
||||
{
|
||||
string res = prep_dir + "/" + to_string(nparties) + "-" + type_short;
|
||||
if (log2mod > 1)
|
||||
res += "-" + to_string(log2mod);
|
||||
res += "/";
|
||||
if (mkdir_p(res.c_str()) < 0)
|
||||
throw file_error(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
16
Math/Setup.h
16
Math/Setup.h
@@ -27,6 +27,7 @@ void generate_prime_setup(string dir, int lgp);
|
||||
template<class T>
|
||||
void generate_online_setup(string dirname, bigint& p, int lgp);
|
||||
void write_online_setup(string dirname, const bigint& p);
|
||||
void check_setup(string dirname, bigint p);
|
||||
|
||||
// Setup primes only
|
||||
// Chooses a p of at least lgp bits
|
||||
@@ -35,22 +36,19 @@ void SPDZ_Data_Setup_Primes(bigint& p,int lgp,int& idx,int& m);
|
||||
void generate_prime(bigint& p, int lgp, int m);
|
||||
bigint generate_prime(int lgp, int m);
|
||||
|
||||
string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod,
|
||||
const string& type_short);
|
||||
|
||||
template<class T>
|
||||
string get_prep_sub_dir(string prep_dir, int nparties, int log2mod)
|
||||
string get_prep_sub_dir(const string& prep_dir, int nparties, int log2mod)
|
||||
{
|
||||
string res = prep_dir + "/" + to_string(nparties) + "-" + T::type_short();
|
||||
if (T::clear::length() > 1)
|
||||
log2mod = T::clear::length();
|
||||
if (log2mod > 1)
|
||||
res += "-" + to_string(log2mod);
|
||||
res += "/";
|
||||
if (mkdir_p(res.c_str()) < 0)
|
||||
throw file_error(res);
|
||||
return res;
|
||||
return get_prep_sub_dir(prep_dir, nparties, log2mod, T::type_short());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
string get_prep_sub_dir(string prep_dir, int nparties)
|
||||
string get_prep_sub_dir(const string& prep_dir, int nparties)
|
||||
{
|
||||
return get_prep_sub_dir<T>(prep_dir, nparties, T::clear::length());
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef MATH_VALUEINTERFACE_H_
|
||||
#define MATH_VALUEINTERFACE_H_
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
class OnlineOptions;
|
||||
class bigint;
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
|
||||
static const false_type characteristic_two;
|
||||
static const false_type prime_field;
|
||||
static const false_type invertible;
|
||||
|
||||
template<class T>
|
||||
static void init(bool mont = true) { (void) mont; }
|
||||
@@ -28,11 +29,13 @@ public:
|
||||
static void read_or_generate_setup(const string&, const OnlineOptions&) {}
|
||||
template<class T>
|
||||
static void generate_setup(string, int, int) {}
|
||||
template<class T>
|
||||
static void write_setup(int) {}
|
||||
static void write_setup(string) {}
|
||||
static void check_setup(string) {}
|
||||
|
||||
static bigint pr() { throw runtime_error("no prime modulus"); }
|
||||
|
||||
static int power_of_two(bool, int) { throw not_implemented(); }
|
||||
|
||||
void normalize() {}
|
||||
|
||||
void randomize_part(PRNG&, int) { throw not_implemented(); }
|
||||
|
||||
55
Math/Z2k.h
55
Math/Z2k.h
@@ -35,21 +35,8 @@ protected:
|
||||
|
||||
|
||||
public:
|
||||
typedef void Inp;
|
||||
typedef void PO;
|
||||
typedef void Square;
|
||||
|
||||
class DummyZ2kProtocol
|
||||
{
|
||||
public:
|
||||
static void assign(Z2& _, const Z2& __, int& ___)
|
||||
{
|
||||
(void) _, (void) __, (void) ___;
|
||||
throw not_implemented();
|
||||
}
|
||||
};
|
||||
typedef DummyZ2kProtocol Protocol;
|
||||
|
||||
static const int N_BITS = K;
|
||||
static const int MAX_EDABITS = K;
|
||||
static const int N_BYTES = (K + 7) / 8;
|
||||
@@ -109,10 +96,6 @@ public:
|
||||
const mp_limb_t* get() const { return a; }
|
||||
|
||||
void convert_destroy(bigint& a) { *this = a; }
|
||||
|
||||
void negate() {
|
||||
throw not_implemented();
|
||||
}
|
||||
|
||||
Z2<K> operator+(const Z2<K>& other) const;
|
||||
Z2<K> operator-(const Z2<K>& other) const;
|
||||
@@ -126,37 +109,30 @@ public:
|
||||
Z2<K> operator/(const Z2& other) const { (void) other; throw division_by_zero(); }
|
||||
|
||||
Z2<K> operator&(const Z2& other) const;
|
||||
Z2<K> operator^(const Z2& other) const;
|
||||
Z2<K> operator|(const Z2& other) const;
|
||||
|
||||
Z2<K>& operator+=(const Z2<K>& other);
|
||||
Z2<K>& operator-=(const Z2<K>& other);
|
||||
Z2<K>& operator*=(const Z2<K>& other);
|
||||
Z2<K>& operator&=(const Z2<K>& other);
|
||||
Z2<K>& operator<<=(int other);
|
||||
Z2<K>& operator>>=(int other);
|
||||
|
||||
Z2<K> operator<<(int i) const;
|
||||
Z2<K> operator>>(int i) const;
|
||||
Z2<K> operator<<(const Z2<K>& i) const { return *this << i.a[0]; }
|
||||
Z2<K> operator>>(const Z2<K>& i) const { return *this >> i.a[0]; }
|
||||
|
||||
bool operator==(const Z2<K>& other) const;
|
||||
bool operator!=(const Z2<K>& other) const { return not (*this == other); }
|
||||
|
||||
void add(const Z2<K>& a, const Z2<K>& b) { *this = a + b; }
|
||||
void add(const Z2<K>& a) { *this += a; }
|
||||
void sub(const Z2<K>& a, const Z2<K>& b) { *this = a - b; }
|
||||
|
||||
template <int M, int L>
|
||||
void mul(const Z2<M>& a, const Z2<L>& b) { *this = Z2<K>::Mul(a, b); }
|
||||
template <int L>
|
||||
void mul(const Integer& a, const Z2<L>& b) { *this = Z2<K>::Mul(Z2<64>(a), b); }
|
||||
|
||||
void mul(const Z2& a) { *this = Z2::Mul(*this, a); }
|
||||
|
||||
void add(octetStream& os) { add(os.consume(size())); }
|
||||
void add(octetStream& os) { *this += (os.consume(size())); }
|
||||
|
||||
Z2 lazy_add(const Z2& x) const;
|
||||
Z2 lazy_mul(const Z2& x) const;
|
||||
|
||||
Z2& invert();
|
||||
void invert(const Z2& a) { *this = a; invert(); }
|
||||
Z2 invert() const;
|
||||
|
||||
Z2 sqrRoot();
|
||||
|
||||
@@ -164,16 +140,6 @@ public:
|
||||
bool is_one() const { return *this == 1; }
|
||||
bool is_bit() const { return is_zero() or is_one(); }
|
||||
|
||||
void SHL(const Z2& a, const bigint& i) { *this = a << i.get_ui(); }
|
||||
void SHR(const Z2& a, const bigint& i) { *this = a >> i.get_ui(); }
|
||||
|
||||
void SHL(const Z2& a, int i) { *this = a << i; }
|
||||
void SHR(const Z2& a, int i) { *this = a >> i; }
|
||||
|
||||
void AND(const Z2& a, const Z2& b);
|
||||
void OR(const Z2& a, const Z2& b);
|
||||
void XOR(const Z2& a, const Z2& b);
|
||||
|
||||
void randomize(PRNG& G, int n = -1);
|
||||
void randomize_part(PRNG& G, int n);
|
||||
void almost_randomize(PRNG& G) { randomize(G); }
|
||||
@@ -321,6 +287,13 @@ Z2<K>& Z2<K>::operator-=(const Z2<K>& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <int K>
|
||||
Z2<K>& Z2<K>::operator*=(const Z2<K>& other)
|
||||
{
|
||||
*this = *this * other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <int K>
|
||||
Z2<K>& Z2<K>::operator&=(const Z2<K>& other)
|
||||
{
|
||||
|
||||
41
Math/Z2k.hpp
41
Math/Z2k.hpp
@@ -71,7 +71,23 @@ template<int K>
|
||||
Z2<K> Z2<K>::operator&(const Z2<K>& other) const
|
||||
{
|
||||
Z2<K> res;
|
||||
res.AND(*this, other);
|
||||
mpn_and_n(res.a, a, other.a, N_WORDS);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
Z2<K> Z2<K>::operator^(const Z2<K>& other) const
|
||||
{
|
||||
Z2<K> res;
|
||||
mpn_xor_n(res.a, a, other.a, N_WORDS);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
Z2<K> Z2<K>::operator|(const Z2<K>& other) const
|
||||
{
|
||||
Z2<K> res;
|
||||
mpn_ior_n(res.a, a, other.a, N_WORDS);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -86,7 +102,7 @@ bool Z2<K>::operator==(const Z2<K>& other) const
|
||||
}
|
||||
|
||||
template<int K>
|
||||
Z2<K>& Z2<K>::invert()
|
||||
Z2<K> Z2<K>::invert() const
|
||||
{
|
||||
if (get_bit(0) != 1)
|
||||
throw division_by_zero();
|
||||
@@ -96,8 +112,7 @@ Z2<K>& Z2<K>::invert()
|
||||
{
|
||||
res += Z2<K>((Z2<K>(1) - Z2<K>::Mul(*this, res)).get_bit(i)) << i;
|
||||
}
|
||||
*this = res;
|
||||
return *this;
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
@@ -115,24 +130,6 @@ Z2<K> Z2<K>::sqrRoot()
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
void Z2<K>::AND(const Z2<K>& x, const Z2<K>& y)
|
||||
{
|
||||
mpn_and_n(a, x.a, y.a, N_WORDS);
|
||||
}
|
||||
|
||||
template<int K>
|
||||
void Z2<K>::OR(const Z2<K>& x, const Z2<K>& y)
|
||||
{
|
||||
mpn_ior_n(a, x.a, y.a, N_WORDS);
|
||||
}
|
||||
|
||||
template<int K>
|
||||
void Z2<K>::XOR(const Z2<K>& x, const Z2<K>& y)
|
||||
{
|
||||
mpn_xor_n(a, x.a, y.a, N_WORDS);
|
||||
}
|
||||
|
||||
template<int K>
|
||||
void Z2<K>::input(istream& s, bool human)
|
||||
{
|
||||
|
||||
@@ -60,18 +60,6 @@ void Zp_Data::init(const bigint& p,bool mont)
|
||||
}
|
||||
|
||||
|
||||
__m128i Zp_Data::get_random128(PRNG& G)
|
||||
{
|
||||
assert(t == 2);
|
||||
while (true)
|
||||
{
|
||||
__m128i res = G.get_doubleword();
|
||||
if (__uint128_t(res) < __uint128_t(int128(prA[1], prA[0]).a))
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void Zp_Data::Mont_Mult(mp_limb_t* z,const mp_limb_t* x,const mp_limb_t* y,int t) const
|
||||
|
||||
@@ -81,12 +81,10 @@ class Zp_Data
|
||||
void Sub(mp_limb_t* ans,const mp_limb_t* x,const mp_limb_t* y) const;
|
||||
void Sub(mp_limb_t* ans,const mp_limb_t* x,const mp_limb_t* y) const;
|
||||
|
||||
__m128i get_random128(PRNG& G);
|
||||
|
||||
bool operator!=(const Zp_Data& other) const;
|
||||
|
||||
template<int L> friend void to_modp(modp_<L>& ans,int x,const Zp_Data& ZpD);
|
||||
template<int L> friend void to_modp(modp_<L>& ans,const bigint& x,const Zp_Data& ZpD);
|
||||
template<int L> friend void to_modp(modp_<L>& ans,const mpz_class& x,const Zp_Data& ZpD);
|
||||
|
||||
template<int L> friend void Add(modp_<L>& ans,const modp_<L>& x,const modp_<L>& y,const Zp_Data& ZpD);
|
||||
template<int L> friend void Sub(modp_<L>& ans,const modp_<L>& x,const modp_<L>& y,const Zp_Data& ZpD);
|
||||
@@ -263,6 +261,13 @@ inline void Zp_Data::Mont_Mult(mp_limb_t* z,const mp_limb_t* x,const mp_limb_t*
|
||||
CASE(4)
|
||||
CASE(5)
|
||||
#endif
|
||||
#if MAX_MOD_SZ >= 10
|
||||
CASE(6)
|
||||
CASE(7)
|
||||
CASE(8)
|
||||
CASE(9)
|
||||
CASE(10)
|
||||
#endif
|
||||
#undef CASE
|
||||
#endif
|
||||
default:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Z2k.h"
|
||||
#include "Z2k.hpp"
|
||||
#include "GC/Clear.h"
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include "bigint.hpp"
|
||||
|
||||
@@ -152,6 +152,13 @@ bigint::bigint(const gfpvar& other)
|
||||
to_bigint(*this, other.get(), other.get_ZpD());
|
||||
}
|
||||
|
||||
string to_string(const bigint& x)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << x;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef REALLOC_POLICE
|
||||
void bigint::lottery()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using namespace std;
|
||||
#include <stddef.h>
|
||||
#include <mpirxx.h>
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
#include "Tools/int.h"
|
||||
#include "Tools/random.h"
|
||||
#include "Tools/octetStream.h"
|
||||
@@ -69,12 +69,14 @@ public:
|
||||
bigint& operator=(word n);
|
||||
template<int X, int L>
|
||||
bigint& operator=(const gfp_<X, L>& other);
|
||||
template<int K>
|
||||
bigint& operator=(const Z2<K>& x);
|
||||
template<int K>
|
||||
bigint& operator=(const SignedZ2<K>& x);
|
||||
|
||||
void allocate_slots(const bigint& x) { *this = x; }
|
||||
int get_min_alloc() { return get_mpz_t()->_mp_alloc; }
|
||||
|
||||
void negate() { mpz_neg(get_mpz_t(), get_mpz_t()); }
|
||||
|
||||
void mul(const bigint& x, const bigint& y) { *this = x * y; }
|
||||
|
||||
#ifdef REALLOC_POLICE
|
||||
@@ -138,12 +140,25 @@ inline bigint& bigint::operator=(word n)
|
||||
|
||||
template<int K>
|
||||
bigint::bigint(const Z2<K>& x)
|
||||
{
|
||||
*this = x;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
bigint& bigint::operator=(const Z2<K>& x)
|
||||
{
|
||||
mpz_import(get_mpz_t(), Z2<K>::N_WORDS, -1, sizeof(mp_limb_t), 0, 0, x.get_ptr());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
bigint::bigint(const SignedZ2<K>& x)
|
||||
{
|
||||
*this = x;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
bigint& bigint::operator=(const SignedZ2<K>& x)
|
||||
{
|
||||
mpz_import(get_mpz_t(), Z2<K>::N_WORDS, -1, sizeof(mp_limb_t), 0, 0, x.get_ptr());
|
||||
if (x.negative())
|
||||
@@ -152,6 +167,7 @@ bigint::bigint(const SignedZ2<K>& x)
|
||||
bigint::tmp <<= K;
|
||||
*this -= bigint::tmp;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<int X, int L>
|
||||
@@ -167,6 +183,7 @@ bigint& bigint::operator=(const gfp_<X, L>& x)
|
||||
return *this;
|
||||
}
|
||||
|
||||
string to_string(const bigint& x);
|
||||
|
||||
/**********************************
|
||||
* Utility Functions *
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Math/gf2n.h"
|
||||
#include "Math/Bit.h"
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wmmintrin.h>
|
||||
@@ -58,7 +58,7 @@ void gf2n_short::init_field(int nn)
|
||||
{
|
||||
if (nn == 0)
|
||||
{
|
||||
nn = default_length();
|
||||
nn = DEFAULT_LENGTH;
|
||||
#ifdef VERBOSE
|
||||
cerr << "Using GF(2^" << nn << ")" << endl;
|
||||
#endif
|
||||
@@ -139,19 +139,6 @@ inline word mul16(word x,word y)
|
||||
|
||||
|
||||
|
||||
/* Takes 16 bit x the 32 bit square */
|
||||
inline word sqr16(word x)
|
||||
{
|
||||
word a1=x&(0xFF),a2=x>>8;
|
||||
|
||||
word ans=gf2n_short_table[a2][a2]<<16;
|
||||
ans^=gf2n_short_table[a1][a1];
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gf2n_short::reduce_trinomial(word xh,word xl)
|
||||
{
|
||||
// Deal with xh first
|
||||
@@ -261,39 +248,9 @@ gf2n_short gf2n_short::operator*(const Bit& x) const
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void sqr32(word x,word& ans)
|
||||
gf2n_short gf2n_short::invert() const
|
||||
{
|
||||
word a1=x&(0xFFFF),a2=x>>16;
|
||||
ans=sqr16(a1)^(sqr16(a2)<<32);
|
||||
}
|
||||
|
||||
void gf2n_short::square()
|
||||
{
|
||||
word xh,xl;
|
||||
sqr32(a&0xFFFFFFFF,xl);
|
||||
sqr32(a>>32,xh);
|
||||
reduce(xh,xl);
|
||||
}
|
||||
|
||||
|
||||
void gf2n_short::square(const gf2n_short& bb)
|
||||
{
|
||||
word xh,xl;
|
||||
sqr32(bb.a&0xFFFFFFFF,xl);
|
||||
sqr32(bb.a>>32,xh);
|
||||
reduce(xh,xl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void gf2n_short::invert()
|
||||
{
|
||||
if (is_one()) { return; }
|
||||
if (is_one()) { return *this; }
|
||||
if (is_zero()) { throw division_by_zero(); }
|
||||
|
||||
word u,v=a,B=0,D=1,mod=1;
|
||||
@@ -322,22 +279,7 @@ void gf2n_short::invert()
|
||||
else { v=v^u; D=D^B; }
|
||||
}
|
||||
|
||||
a=D;
|
||||
}
|
||||
|
||||
|
||||
void gf2n_short::power(long i)
|
||||
{
|
||||
long n=i;
|
||||
if (n<0) { invert(); n=-n; }
|
||||
|
||||
gf2n_short T=*this;
|
||||
assign_one();
|
||||
while (n!=0)
|
||||
{ if ((n&1)!=0) { mul(*this,T); }
|
||||
n>>=1;
|
||||
T.square();
|
||||
}
|
||||
return D;
|
||||
}
|
||||
|
||||
|
||||
@@ -380,14 +322,14 @@ void gf2n_short::input(istream& s,bool human)
|
||||
void expand_byte(gf2n_short& a,int b)
|
||||
{
|
||||
gf2n_short x,xp;
|
||||
x.assign(32+1);
|
||||
x = (32+1);
|
||||
xp.assign_one();
|
||||
a.assign_zero();
|
||||
|
||||
while (b!=0)
|
||||
{ if ((b&1)==1)
|
||||
{ a.add(a,xp); }
|
||||
xp.mul(x);
|
||||
xp *= (x);
|
||||
b>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
70
Math/gf2n.h
70
Math/gf2n.h
@@ -66,8 +66,7 @@ class gf2n_short : public ValueInterface
|
||||
|
||||
static const int MAX_N_BITS = 64;
|
||||
static const int N_BYTES = sizeof(a);
|
||||
|
||||
static const int N_BITS = -1;
|
||||
static const int DEFAULT_LENGTH = 40;
|
||||
|
||||
static void init_field(int nn = 0);
|
||||
static void reset() { n = 0; }
|
||||
@@ -88,10 +87,8 @@ class gf2n_short : public ValueInterface
|
||||
|
||||
static int size() { return sizeof(a); }
|
||||
static int size_in_bits() { return sizeof(a) * 8; }
|
||||
static int t() { return 0; }
|
||||
|
||||
static int default_length() { return 40; }
|
||||
static int length() { return n == 0 ? default_length() : n; }
|
||||
static int length() { return n == 0 ? DEFAULT_LENGTH : n; }
|
||||
|
||||
static bool allows(Dtype type) { (void) type; return true; }
|
||||
|
||||
@@ -107,17 +104,12 @@ class gf2n_short : public ValueInterface
|
||||
|
||||
const void* get_ptr() const { return &a; }
|
||||
|
||||
void assign(const gf2n_short& g) { a=g.a; }
|
||||
|
||||
void assign_zero() { a=0; }
|
||||
void assign_one() { a=1; }
|
||||
void assign_x() { a=2; }
|
||||
void assign(word aa) { a=aa&mask; }
|
||||
void assign(long aa) { assign(word(aa)); }
|
||||
void assign(int aa) { a=static_cast<unsigned int>(aa)&mask; }
|
||||
void assign(const void* aa) { a = *(word*) aa & mask; }
|
||||
|
||||
void normalize() { assign(a); }
|
||||
void normalize() { a &= mask; }
|
||||
|
||||
int get_bit(int i) const
|
||||
{ return (a>>i)&1; }
|
||||
@@ -129,37 +121,29 @@ class gf2n_short : public ValueInterface
|
||||
}
|
||||
|
||||
gf2n_short() : a(0) {}
|
||||
gf2n_short(word a) { assign(a); }
|
||||
gf2n_short(long a) { assign(a); }
|
||||
gf2n_short(int a) { assign(a); }
|
||||
gf2n_short(bool a) { assign(a); }
|
||||
gf2n_short(const char* a) { assign(a); }
|
||||
gf2n_short(word a) : a(a & mask) {}
|
||||
gf2n_short(long a) : gf2n_short(word(a)) {}
|
||||
gf2n_short(int a) : gf2n_short(word(unsigned(a))) {}
|
||||
gf2n_short(const int128& a) { reduce(a.get_upper(), a.get_lower()); }
|
||||
template<class T>
|
||||
gf2n_short(IntBase<T> a) { assign(a.get()); }
|
||||
gf2n_short(IntBase<T> a) : a(a.get()) {}
|
||||
|
||||
int is_zero() const { return (a==0); }
|
||||
int is_one() const { return (a==1); }
|
||||
int equal(const gf2n_short& y) const { return (a==y.a); }
|
||||
bool operator==(const gf2n_short& y) const { return a==y.a; }
|
||||
bool operator!=(const gf2n_short& y) const { return a!=y.a; }
|
||||
|
||||
// x+y
|
||||
void add(const gf2n_short& x,const gf2n_short& y)
|
||||
{ a=x.a^y.a; }
|
||||
void add(const gf2n_short& x)
|
||||
{ a^=x.a; }
|
||||
void add(octet* x)
|
||||
{ a^=*(word*)(x); }
|
||||
void add(octetStream& os)
|
||||
{ add(os.consume(size())); }
|
||||
void sub(const gf2n_short& x,const gf2n_short& y)
|
||||
{ a=x.a^y.a; }
|
||||
void sub(const gf2n_short& x)
|
||||
{ a^=x.a; }
|
||||
// = x * y
|
||||
void mul(const gf2n_short& x,const gf2n_short& y);
|
||||
void mul(const gf2n_short& x) { mul(*this,x); }
|
||||
// x * y when one of x,y is a bit
|
||||
void mul_by_bit(const gf2n_short& x, const gf2n_short& y) { a = x.a * y.a; }
|
||||
|
||||
@@ -168,40 +152,28 @@ class gf2n_short : public ValueInterface
|
||||
|
||||
gf2n_short operator+(const gf2n_short& x) const { gf2n_short res; res.add(*this, x); return res; }
|
||||
gf2n_short operator*(const gf2n_short& x) const { gf2n_short res; res.mul(*this, x); return res; }
|
||||
gf2n_short& operator+=(const gf2n_short& x) { add(x); return *this; }
|
||||
gf2n_short& operator*=(const gf2n_short& x) { mul(x); return *this; }
|
||||
gf2n_short& operator+=(const gf2n_short& x) { add(*this, x); return *this; }
|
||||
gf2n_short& operator*=(const gf2n_short& x) { mul(*this, x); return *this; }
|
||||
gf2n_short operator-(const gf2n_short& x) const { gf2n_short res; res.add(*this, x); return res; }
|
||||
gf2n_short& operator-=(const gf2n_short& x) { sub(x); return *this; }
|
||||
gf2n_short operator/(const gf2n_short& x) const { gf2n_short tmp; tmp.invert(x); return *this * tmp; }
|
||||
gf2n_short& operator-=(const gf2n_short& x) { sub(*this, x); return *this; }
|
||||
gf2n_short operator/(const gf2n_short& x) const { return *this * x.invert(); }
|
||||
|
||||
gf2n_short operator*(const Bit& x) const;
|
||||
|
||||
void square();
|
||||
void square(const gf2n_short& aa);
|
||||
void invert();
|
||||
void invert(const gf2n_short& aa)
|
||||
{ *this=aa; invert(); }
|
||||
gf2n_short invert() const;
|
||||
void negate() { return; }
|
||||
void power(long i);
|
||||
|
||||
/* Bitwise Ops */
|
||||
void AND(const gf2n_short& x,const gf2n_short& y) { a=x.a&y.a; }
|
||||
void XOR(const gf2n_short& x,const gf2n_short& y) { a=x.a^y.a; }
|
||||
void OR(const gf2n_short& x,const gf2n_short& y) { a=x.a|y.a; }
|
||||
void NOT(const gf2n_short& x) { a=(~x.a)&mask; }
|
||||
void SHL(const gf2n_short& x,int n) { a=(x.a<<n)&mask; }
|
||||
void SHR(const gf2n_short& x,int n) { a=x.a>>n; }
|
||||
gf2n_short operator&(const gf2n_short& x) const { return a & x.a; }
|
||||
gf2n_short operator^(const gf2n_short& x) const { return a ^ x.a; }
|
||||
gf2n_short operator|(const gf2n_short& x) const { return a | x.a; }
|
||||
gf2n_short operator~() const { return ~a; }
|
||||
gf2n_short operator<<(int i) const { return a << i; }
|
||||
gf2n_short operator>>(int i) const { return a >> i; }
|
||||
|
||||
gf2n_short operator&(const gf2n_short& x) const { gf2n_short res; res.AND(*this, x); return res; }
|
||||
gf2n_short operator^(const gf2n_short& x) const { gf2n_short res; res.XOR(*this, x); return res; }
|
||||
gf2n_short operator|(const gf2n_short& x) const { gf2n_short res; res.OR(*this, x); return res; }
|
||||
gf2n_short operator!() const { gf2n_short res; res.NOT(*this); return res; }
|
||||
gf2n_short operator<<(int i) const { gf2n_short res; res.SHL(*this, i); return res; }
|
||||
gf2n_short operator>>(int i) const { gf2n_short res; res.SHR(*this, i); return res; }
|
||||
|
||||
gf2n_short& operator&=(const gf2n_short& x) { AND(*this, x); return *this; }
|
||||
gf2n_short& operator>>=(int i) { SHR(*this, i); return *this; }
|
||||
gf2n_short& operator<<=(int i) { SHL(*this, i); return *this; }
|
||||
gf2n_short& operator&=(const gf2n_short& x) { *this = *this & x; return *this; }
|
||||
gf2n_short& operator>>=(int i) { *this = *this >> i; return *this; }
|
||||
gf2n_short& operator<<=(int i) { *this = *this << i; return *this; }
|
||||
|
||||
/* Crap RNG */
|
||||
void randomize(PRNG& G, int n = -1);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "gf2nlong.h"
|
||||
#include "gf2n.h"
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wmmintrin.h>
|
||||
@@ -66,7 +66,7 @@ void gf2n_long::init_field(int nn)
|
||||
{
|
||||
if (nn == 0)
|
||||
{
|
||||
nn = default_length();
|
||||
nn = MAX_N_BITS;
|
||||
#ifdef VERBOSE
|
||||
cerr << "Using GF(2^" << nn << ")" << endl;
|
||||
#endif
|
||||
@@ -201,9 +201,9 @@ public:
|
||||
{ s << a.msb << a.lower; return s; }
|
||||
};
|
||||
|
||||
void gf2n_long::invert()
|
||||
gf2n_long gf2n_long::invert() const
|
||||
{
|
||||
if (is_one()) { return; }
|
||||
if (is_one()) { return *this; }
|
||||
if (is_zero()) { throw division_by_zero(); }
|
||||
|
||||
int129 u,v=a,B=0,D=1,mod=1;
|
||||
@@ -232,7 +232,7 @@ void gf2n_long::invert()
|
||||
else { v=v^u; D=D^B; }
|
||||
}
|
||||
|
||||
a=D.get_lower();
|
||||
return D.get_lower();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ using namespace std;
|
||||
#include "Tools/random.h"
|
||||
#include "Math/field_types.h"
|
||||
#include "Math/bigint.h"
|
||||
#include "Math/Bit.h"
|
||||
|
||||
|
||||
class int128
|
||||
@@ -59,7 +58,6 @@ public:
|
||||
|
||||
friend ostream& operator<<(ostream& s, const int128& a);
|
||||
|
||||
static int128 ones(int n);
|
||||
bool get_bit(int i) const;
|
||||
};
|
||||
|
||||
@@ -108,8 +106,6 @@ class gf2n_long : public ValueInterface
|
||||
const static int MAX_N_BITS = 128;
|
||||
const static int N_BYTES = sizeof(a);
|
||||
|
||||
static const int N_BITS = -1;
|
||||
|
||||
typedef gf2n_long Scalar;
|
||||
|
||||
void reduce(int128 xh,int128 xl)
|
||||
@@ -139,9 +135,6 @@ class gf2n_long : public ValueInterface
|
||||
|
||||
static int size() { return sizeof(a); }
|
||||
static int size_in_bits() { return sizeof(a) * 8; }
|
||||
static int t() { return 0; }
|
||||
|
||||
static int default_length() { return 128; }
|
||||
|
||||
static bool allows(Dtype type) { (void) type; return true; }
|
||||
|
||||
@@ -157,39 +150,19 @@ class gf2n_long : public ValueInterface
|
||||
|
||||
const void* get_ptr() const { return &a.a; }
|
||||
|
||||
void assign(const gf2n_long& g) { a=g.a; }
|
||||
|
||||
void assign_zero() { a=_mm_setzero_si128(); }
|
||||
void assign_one() { a=int128(0,1); }
|
||||
void assign_x() { a=int128(0,2); }
|
||||
void assign(int128 aa) { a=aa&mask; }
|
||||
void assign(int aa) { a=int128(static_cast<unsigned int>(aa))&mask; }
|
||||
void assign(const void* buffer) { a = _mm_loadu_si128((__m128i*)buffer); }
|
||||
|
||||
void normalize() {}
|
||||
|
||||
int get_bit(int i) const
|
||||
{ return ((a>>i)&1).get_lower(); }
|
||||
void set_bit(int i,unsigned int b)
|
||||
{ if (b==1)
|
||||
{ a |= (1UL<<i); }
|
||||
else
|
||||
{ a &= ~(1UL<<i); }
|
||||
}
|
||||
|
||||
gf2n_long() { assign_zero(); }
|
||||
gf2n_long(const gf2n_long& g) { assign(g); }
|
||||
gf2n_long(const int128& g) { assign(g); }
|
||||
gf2n_long(int g) { assign(g); }
|
||||
gf2n_long(const int128& g) : a(g & mask) {}
|
||||
gf2n_long(int g) : gf2n_long(int128(unsigned(g))) {}
|
||||
template<class T>
|
||||
gf2n_long(IntBase<T> g) { assign(g.get()); }
|
||||
gf2n_long(const char* buffer) { assign(buffer); }
|
||||
gf2n_long(GC::NoValue);
|
||||
|
||||
gf2n_long& operator=(const gf2n_long& g)
|
||||
{ if (&g!=this) { assign(g); }
|
||||
return *this;
|
||||
}
|
||||
gf2n_long(IntBase<T> g) : a(g.get()) {}
|
||||
|
||||
int is_zero() const { return a==int128(0); }
|
||||
int is_one() const { return a==int128(1); }
|
||||
@@ -200,19 +173,14 @@ class gf2n_long : public ValueInterface
|
||||
// x+y
|
||||
void add(const gf2n_long& x,const gf2n_long& y)
|
||||
{ a=x.a^y.a; }
|
||||
void add(const gf2n_long& x)
|
||||
{ a^=x.a; }
|
||||
void add(octet* x)
|
||||
{ a^=int128(_mm_loadu_si128((__m128i*)x)); }
|
||||
void add(octetStream& os)
|
||||
{ add(os.consume(size())); }
|
||||
void sub(const gf2n_long& x,const gf2n_long& y)
|
||||
{ a=x.a^y.a; }
|
||||
void sub(const gf2n_long& x)
|
||||
{ a^=x.a; }
|
||||
// = x * y
|
||||
gf2n_long& mul(const gf2n_long& x,const gf2n_long& y);
|
||||
void mul(const gf2n_long& x) { mul(*this,x); }
|
||||
// x * y when one of x,y is a bit
|
||||
void mul_by_bit(const gf2n_long& x, const gf2n_long& y) { a = x.a.a * y.a.a; }
|
||||
|
||||
@@ -221,40 +189,27 @@ class gf2n_long : public ValueInterface
|
||||
|
||||
gf2n_long operator+(const gf2n_long& x) const { gf2n_long res; res.add(*this, x); return res; }
|
||||
gf2n_long operator*(const gf2n_long& x) const { gf2n_long res; res.mul(*this, x); return res; }
|
||||
gf2n_long& operator+=(const gf2n_long& x) { add(x); return *this; }
|
||||
gf2n_long& operator*=(const gf2n_long& x) { mul(x); return *this; }
|
||||
gf2n_long& operator+=(const gf2n_long& x) { add(*this, x); return *this; }
|
||||
gf2n_long& operator*=(const gf2n_long& x) { mul(*this, x); return *this; }
|
||||
gf2n_long operator-(const gf2n_long& x) const { gf2n_long res; res.add(*this, x); return res; }
|
||||
gf2n_long& operator-=(const gf2n_long& x) { sub(x); return *this; }
|
||||
gf2n_long operator/(const gf2n_long& x) const { gf2n_long tmp; tmp.invert(x); return *this * tmp; }
|
||||
gf2n_long& operator-=(const gf2n_long& x) { sub(*this, x); return *this; }
|
||||
gf2n_long operator/(const gf2n_long& x) const { return *this * x.invert(); }
|
||||
|
||||
void square();
|
||||
void square(const gf2n_long& aa);
|
||||
void invert();
|
||||
void invert(const gf2n_long& aa)
|
||||
{ *this=aa; invert(); }
|
||||
gf2n_long invert() const;
|
||||
void negate() { return; }
|
||||
void power(long i);
|
||||
|
||||
/* Bitwise Ops */
|
||||
void AND(const gf2n_long& x,const gf2n_long& y) { a=x.a&y.a; }
|
||||
void XOR(const gf2n_long& x,const gf2n_long& y) { a=x.a^y.a; }
|
||||
void OR(const gf2n_long& x,const gf2n_long& y) { a=x.a|y.a; }
|
||||
void NOT(const gf2n_long& x) { a=(~x.a)&mask; }
|
||||
void SHL(const gf2n_long& x,int n) { a=(x.a<<n)&mask; }
|
||||
void SHR(const gf2n_long& x,int n) { a=x.a>>n; }
|
||||
gf2n_long operator&(const gf2n_long& x) const { return a & x.a; }
|
||||
gf2n_long operator^(const gf2n_long& x) const { return a ^ x.a; }
|
||||
gf2n_long operator|(const gf2n_long& x) const { return a | x.a; }
|
||||
gf2n_long operator~() const { return ~a; }
|
||||
gf2n_long operator<<(int i) const { return a << i; }
|
||||
gf2n_long operator>>(int i) const { return a >> i; }
|
||||
|
||||
gf2n_long operator&(const gf2n_long& x) const { gf2n_long res; res.AND(*this, x); return res; }
|
||||
gf2n_long operator^(const gf2n_long& x) const { gf2n_long res; res.XOR(*this, x); return res; }
|
||||
gf2n_long operator|(const gf2n_long& x) const { gf2n_long res; res.OR(*this, x); return res; }
|
||||
gf2n_long operator!() const { gf2n_long res; res.NOT(*this); return res; }
|
||||
gf2n_long operator<<(int i) const { gf2n_long res; res.SHL(*this, i); return res; }
|
||||
gf2n_long operator>>(int i) const { gf2n_long res; res.SHR(*this, i); return res; }
|
||||
|
||||
gf2n_long& operator&=(const gf2n_long& x) { AND(*this, x); return *this; }
|
||||
gf2n_long& operator>>=(int i) { SHR(*this, i); return *this; }
|
||||
gf2n_long& operator<<=(int i) { SHL(*this, i); return *this; }
|
||||
|
||||
bool operator<(gf2n_long) const { return false; }
|
||||
gf2n_long& operator&=(const gf2n_long& x) { *this = *this & x; return *this; }
|
||||
gf2n_long& operator^=(const gf2n_long& x) { *this = *this ^ x; return *this; }
|
||||
gf2n_long& operator>>=(int i) { *this = *this >> i; return *this; }
|
||||
gf2n_long& operator<<=(int i) { *this = *this << i; return *this; }
|
||||
|
||||
/* Crap RNG */
|
||||
void randomize(PRNG& G, int n = -1);
|
||||
@@ -263,9 +218,6 @@ class gf2n_long : public ValueInterface
|
||||
|
||||
void force_to_bit() { a &= 1; }
|
||||
|
||||
template<class T>
|
||||
T convert() const { return *this; }
|
||||
|
||||
void output(ostream& s,bool human) const;
|
||||
void input(istream& s,bool human);
|
||||
|
||||
@@ -277,7 +229,10 @@ class gf2n_long : public ValueInterface
|
||||
{ bigint tmp;
|
||||
s >> hex >> tmp >> dec;
|
||||
x.a = 0;
|
||||
mpn_copyi((word*)&x.a.a, tmp.get_mpz_t()->_mp_d, tmp.get_mpz_t()->_mp_size);
|
||||
auto size = tmp.get_mpz_t()->_mp_size;
|
||||
assert(size >= 0);
|
||||
assert(size <= 2);
|
||||
mpn_copyi((mp_limb_t*)&x.a.a, tmp.get_mpz_t()->_mp_d, size);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -357,14 +312,6 @@ inline void mul128(__m128i a, __m128i b, __m128i *res1, __m128i *res2)
|
||||
*res2 = tmp6;
|
||||
}
|
||||
|
||||
inline int128 int128::ones(int n)
|
||||
{
|
||||
if (n < 64)
|
||||
return int128(0, (1ULL << n) - 1);
|
||||
else
|
||||
return int128((1ULL << (n - 64)) - 1, -1);
|
||||
}
|
||||
|
||||
inline bool int128::get_bit(int i) const
|
||||
{
|
||||
if (i < 64)
|
||||
|
||||
107
Math/gfp.h
107
Math/gfp.h
@@ -9,6 +9,7 @@ using namespace std;
|
||||
#include "Math/Zp_Data.h"
|
||||
#include "Math/field_types.h"
|
||||
#include "Math/Bit.h"
|
||||
#include "Math/Setup.h"
|
||||
#include "Tools/random.h"
|
||||
#include "GC/NoShare.h"
|
||||
#include "Processor/OnlineOptions.h"
|
||||
@@ -78,8 +79,14 @@ class gfp_ : public ValueInterface
|
||||
template<class T>
|
||||
static void generate_setup(string dir, int nplayers, int lgp)
|
||||
{ generate_prime_setup<T>(dir, nplayers, lgp); }
|
||||
template<class T>
|
||||
static void write_setup(int nplayers)
|
||||
{ write_setup(get_prep_sub_dir<T>(nplayers)); }
|
||||
static void write_setup(string dir)
|
||||
{ write_online_setup(dir, pr()); }
|
||||
static void check_setup(string dir);
|
||||
|
||||
static bigint pr()
|
||||
static const bigint& pr()
|
||||
{ return ZpD.pr; }
|
||||
static int t()
|
||||
{ return L; }
|
||||
@@ -108,19 +115,9 @@ class gfp_ : public ValueInterface
|
||||
|
||||
static gfp_ power_of_two(bool bit, int exp);
|
||||
|
||||
void assign(const gfp_& g) { a=g.a; }
|
||||
void assign_zero() { assignZero(a,ZpD); }
|
||||
void assign_one() { assignOne(a,ZpD); }
|
||||
void assign(word aa) { bigint::tmp=aa; to_gfp(*this,bigint::tmp); }
|
||||
void assign(long aa)
|
||||
{
|
||||
if (aa == 0)
|
||||
assignZero(a, ZpD);
|
||||
else
|
||||
to_gfp(*this, bigint::tmp = aa);
|
||||
}
|
||||
void assign(int aa) { assign(long(aa)); }
|
||||
void assign(const char* buffer) { a.assign(buffer, ZpD.get_t()); }
|
||||
void assign(const void* buffer) { a.assign(buffer, ZpD.get_t()); }
|
||||
|
||||
modp_type get() const { return a; }
|
||||
|
||||
@@ -129,33 +126,20 @@ class gfp_ : public ValueInterface
|
||||
const void* get_ptr() const { return &a.x; }
|
||||
void* get_ptr() { return &a.x; }
|
||||
|
||||
// Assumes prD behind x is equal to ZpD
|
||||
void assign(modp_<L>& x) { a=x; }
|
||||
|
||||
gfp_() { assignZero(a,ZpD); }
|
||||
template<int LL>
|
||||
gfp_(const modp_<LL>& g) { a=g; }
|
||||
gfp_(const __m128i& x) { *this=x; }
|
||||
gfp_(const int128& x) { *this=x.a; }
|
||||
gfp_(const bigint& x) { to_modp(a, x, ZpD); }
|
||||
gfp_(int x) { assign(x); }
|
||||
gfp_(long x) { assign(x); }
|
||||
gfp_(word x) { assign(x); }
|
||||
gfp_(const mpz_class& x) { to_modp(a, x, ZpD); }
|
||||
gfp_(int x) : gfp_(long(x)) {}
|
||||
gfp_(long x);
|
||||
gfp_(word x) : gfp_(bigint::tmp = x) {}
|
||||
template<class T>
|
||||
gfp_(IntBase<T> x) { assign(x.get()); }
|
||||
gfp_(const void* buffer) { assign((char*)buffer); }
|
||||
gfp_(IntBase<T> x) : gfp_(x.get()) {}
|
||||
template<int Y>
|
||||
gfp_(const gfp_<Y, L>& x);
|
||||
gfp_(const gfpvar& other);
|
||||
template<int K>
|
||||
gfp_(const SignedZ2<K>& other);
|
||||
gfp_(GC::NoValue) { GC::NoValue::fail(); }
|
||||
|
||||
gfp_& operator=(const __m128i other)
|
||||
{
|
||||
memcpy(a.x, &other, sizeof(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void zero_overhang();
|
||||
void check();
|
||||
@@ -172,19 +156,13 @@ class gfp_ : public ValueInterface
|
||||
{ add(os.consume(size())); }
|
||||
void add(const gfp_& x,const gfp_& y)
|
||||
{ ZpD.Add<L>(a.x,x.a.x,y.a.x); }
|
||||
void add(const gfp_& x)
|
||||
{ ZpD.Add<L>(a.x,a.x,x.a.x); }
|
||||
void add(void* x)
|
||||
{ ZpD.Add<L>(a.x,a.x,(mp_limb_t*)x); }
|
||||
void sub(const gfp_& x,const gfp_& y)
|
||||
{ Sub(a,x.a,y.a,ZpD); }
|
||||
void sub(const gfp_& x)
|
||||
{ Sub(a,a,x.a,ZpD); }
|
||||
// = x * y
|
||||
void mul(const gfp_& x,const gfp_& y)
|
||||
{ a.template mul<L>(x.a,y.a,ZpD); }
|
||||
void mul(const gfp_& x)
|
||||
{ a.template mul<L>(a,x.a,ZpD); }
|
||||
|
||||
gfp_ lazy_add(const gfp_& x) const { return *this + x; }
|
||||
gfp_ lazy_mul(const gfp_& x) const { return *this * x; }
|
||||
@@ -192,25 +170,16 @@ class gfp_ : public ValueInterface
|
||||
gfp_ operator+(const gfp_& x) const { gfp_ res; res.add(*this, x); return res; }
|
||||
gfp_ operator-(const gfp_& x) const { gfp_ res; res.sub(*this, x); return res; }
|
||||
gfp_ operator*(const gfp_& x) const { gfp_ res; res.mul(*this, x); return res; }
|
||||
gfp_ operator/(const gfp_& x) const { gfp_ tmp; tmp.invert(x); return *this * tmp; }
|
||||
gfp_& operator+=(const gfp_& x) { add(x); return *this; }
|
||||
gfp_& operator-=(const gfp_& x) { sub(x); return *this; }
|
||||
gfp_& operator*=(const gfp_& x) { mul(x); return *this; }
|
||||
gfp_ operator/(const gfp_& x) const { return *this * x.invert(); }
|
||||
gfp_& operator+=(const gfp_& x) { add(*this, x); return *this; }
|
||||
gfp_& operator-=(const gfp_& x) { sub(*this, x); return *this; }
|
||||
gfp_& operator*=(const gfp_& x) { mul(*this, x); return *this; }
|
||||
|
||||
gfp_ operator-() { gfp_ res = *this; res.negate(); return res; }
|
||||
|
||||
void square(const gfp_& aa)
|
||||
{ Sqr(a,aa.a,ZpD); }
|
||||
void square()
|
||||
{ Sqr(a,a,ZpD); }
|
||||
void invert()
|
||||
{ Inv(a,a,ZpD); }
|
||||
void invert(const gfp_& aa)
|
||||
{ Inv(a,aa.a,ZpD); }
|
||||
gfp_ invert() const;
|
||||
void negate()
|
||||
{ Negate(a,a,ZpD); }
|
||||
void power(long i)
|
||||
{ Power(a,a,i,ZpD); }
|
||||
|
||||
// deterministic square root
|
||||
gfp_ sqrRoot();
|
||||
@@ -237,26 +206,17 @@ class gfp_ : public ValueInterface
|
||||
/* Bitwise Ops
|
||||
* - Converts gfp args to bigints and then converts answer back to gfp
|
||||
*/
|
||||
void AND(const gfp_& x,const gfp_& y);
|
||||
void XOR(const gfp_& x,const gfp_& y);
|
||||
void OR(const gfp_& x,const gfp_& y);
|
||||
void AND(const gfp_& x,const bigint& y);
|
||||
void XOR(const gfp_& x,const bigint& y);
|
||||
void OR(const gfp_& x,const bigint& y);
|
||||
void SHL(const gfp_& x,int n);
|
||||
void SHR(const gfp_& x,int n);
|
||||
void SHL(const gfp_& x,const bigint& n);
|
||||
void SHR(const gfp_& x,const bigint& n);
|
||||
gfp_ operator&(const gfp_& x) { return (bigint::tmp = *this) &= bigint(x); }
|
||||
gfp_ operator^(const gfp_& x) { return (bigint::tmp = *this) ^= bigint(x); }
|
||||
gfp_ operator|(const gfp_& x) { return (bigint::tmp = *this) |= bigint(x); }
|
||||
gfp_ operator<<(int i) const;
|
||||
gfp_ operator>>(int i) const;
|
||||
gfp_ operator<<(const gfp_& i) const;
|
||||
gfp_ operator>>(const gfp_& i) const;
|
||||
|
||||
gfp_ operator&(const gfp_& x) { gfp_ res; res.AND(*this, x); return res; }
|
||||
gfp_ operator^(const gfp_& x) { gfp_ res; res.XOR(*this, x); return res; }
|
||||
gfp_ operator|(const gfp_& x) { gfp_ res; res.OR(*this, x); return res; }
|
||||
gfp_ operator<<(int i) const { gfp_ res; res.SHL(*this, i); return res; }
|
||||
gfp_ operator>>(int i) const { gfp_ res; res.SHR(*this, i); return res; }
|
||||
|
||||
gfp_& operator&=(const gfp_& x) { AND(*this, x); return *this; }
|
||||
gfp_& operator<<=(int i) { SHL(*this, i); return *this; }
|
||||
gfp_& operator>>=(int i) { SHR(*this, i); return *this; }
|
||||
gfp_& operator&=(const gfp_& x) { *this = *this & x; return *this; }
|
||||
gfp_& operator<<=(int i) { *this << i; return *this; }
|
||||
gfp_& operator>>=(int i) { *this >> i; return *this; }
|
||||
|
||||
void force_to_bit() { throw runtime_error("impossible"); }
|
||||
|
||||
@@ -285,6 +245,15 @@ Zp_Data gfp_<X, L>::ZpD;
|
||||
template<int X, int L>
|
||||
thread_local vector<gfp_<X, L>> gfp_<X, L>::powers;
|
||||
|
||||
template<int X, int L>
|
||||
gfp_<X, L>::gfp_(long x)
|
||||
{
|
||||
if (x == 0)
|
||||
assign_zero();
|
||||
else
|
||||
*this = bigint::tmp = x;
|
||||
}
|
||||
|
||||
template<int X, int L>
|
||||
template<int Y>
|
||||
gfp_<X, L>::gfp_(const gfp_<Y, L>& x)
|
||||
|
||||
114
Math/gfp.hpp
114
Math/gfp.hpp
@@ -5,7 +5,7 @@
|
||||
#include "Math/gfpvar.h"
|
||||
#include "Math/Setup.h"
|
||||
|
||||
#include "Exceptions/Exceptions.h"
|
||||
#include "Tools/Exceptions.h"
|
||||
|
||||
#include "Math/bigint.hpp"
|
||||
#include "Math/Setup.hpp"
|
||||
@@ -27,22 +27,26 @@ inline void gfp_<X, L>::read_or_generate_setup(string dir,
|
||||
init_field(opts.prime);
|
||||
}
|
||||
|
||||
template<int X, int L>
|
||||
void gfp_<X, L>::check_setup(string dir)
|
||||
{
|
||||
::check_setup(dir, pr());
|
||||
}
|
||||
|
||||
template<int X, int L>
|
||||
void gfp_<X, L>::init_field(const bigint& p, bool mont)
|
||||
{
|
||||
ZpD.init(p, mont);
|
||||
string name = "gfp<" + to_string(X) + ", " + to_string(L) + ">";
|
||||
char name[100];
|
||||
snprintf(name, 100, "gfp_<%d, %d>", X, L);
|
||||
if (ZpD.get_t() > L)
|
||||
{
|
||||
cout << "modulus is " << p << endl;
|
||||
throw wrong_gfp_size(name + " too small for modulus. "
|
||||
"Maybe change GFP_MOD_SZ to " + to_string(ZpD.get_t()));
|
||||
throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t());
|
||||
}
|
||||
if (ZpD.get_t() < L)
|
||||
{
|
||||
if (mont)
|
||||
throw wrong_gfp_size(name + " too large for modulus. "
|
||||
"Maybe change GFP_MOD_SZ to " + to_string(ZpD.get_t()));
|
||||
throw wrong_gfp_size(name, p, "GFP_MOD_SZ", ZpD.get_t());
|
||||
else
|
||||
cerr << name << " larger than necessary for modulus " << p << endl;
|
||||
}
|
||||
@@ -74,121 +78,69 @@ void gfp_<X, L>::almost_randomize(PRNG& G)
|
||||
a.x[t()-1]&=ZpD.mask;
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::AND(const gfp_& x,const gfp_& y)
|
||||
{
|
||||
bigint bi1,bi2;
|
||||
to_bigint(bi1,x);
|
||||
to_bigint(bi2,y);
|
||||
mpz_and(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t());
|
||||
convert_destroy(bi1);
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::OR(const gfp_& x,const gfp_& y)
|
||||
{
|
||||
bigint bi1,bi2;
|
||||
to_bigint(bi1,x);
|
||||
to_bigint(bi2,y);
|
||||
mpz_ior(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t());
|
||||
convert_destroy(bi1);
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::XOR(const gfp_& x,const gfp_& y)
|
||||
{
|
||||
bigint bi1,bi2;
|
||||
to_bigint(bi1,x);
|
||||
to_bigint(bi2,y);
|
||||
mpz_xor(bi1.get_mpz_t(), bi1.get_mpz_t(), bi2.get_mpz_t());
|
||||
convert_destroy(bi1);
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::AND(const gfp_& x,const bigint& y)
|
||||
{
|
||||
bigint bi;
|
||||
to_bigint(bi,x);
|
||||
mpz_and(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t());
|
||||
convert_destroy(bi);
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::OR(const gfp_& x,const bigint& y)
|
||||
{
|
||||
bigint bi;
|
||||
to_bigint(bi,x);
|
||||
mpz_ior(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t());
|
||||
convert_destroy(bi);
|
||||
}
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::XOR(const gfp_& x,const bigint& y)
|
||||
{
|
||||
bigint bi;
|
||||
to_bigint(bi,x);
|
||||
mpz_xor(bi.get_mpz_t(), bi.get_mpz_t(), y.get_mpz_t());
|
||||
convert_destroy(bi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::SHL(const gfp_& x,int n)
|
||||
gfp_<X, L> gfp_<X, L>::operator<<(int n) const
|
||||
{
|
||||
if (!x.is_zero())
|
||||
if (!is_zero())
|
||||
{
|
||||
if (n != 0)
|
||||
{
|
||||
*this = x * power_of_two(1, n);
|
||||
return *this * power_of_two(1, n);
|
||||
}
|
||||
else
|
||||
assign(x);
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
assign_zero();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::SHR(const gfp_& x,int n)
|
||||
gfp_<X, L> gfp_<X, L>::operator>>(int n) const
|
||||
{
|
||||
if (!x.is_zero())
|
||||
if (!is_zero())
|
||||
{
|
||||
if (n != 0)
|
||||
{
|
||||
bigint& bi = bigint::tmp;
|
||||
to_bigint(bi,x);
|
||||
bi >>= n;
|
||||
convert_destroy(bi);
|
||||
return (bigint::tmp = *this) >>= n;
|
||||
}
|
||||
else
|
||||
assign(x);
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
assign_zero();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::SHL(const gfp_& x,const bigint& n)
|
||||
gfp_<X, L> gfp_<X, L>::operator<<(const gfp_& i) const
|
||||
{
|
||||
SHL(x,mpz_get_si(n.get_mpz_t()));
|
||||
return *this << (bigint::tmp = i).get_ui();
|
||||
}
|
||||
|
||||
|
||||
template <int X, int L>
|
||||
void gfp_<X, L>::SHR(const gfp_& x,const bigint& n)
|
||||
gfp_<X, L> gfp_<X, L>::operator>>(const gfp_& i) const
|
||||
{
|
||||
SHR(x,mpz_get_si(n.get_mpz_t()));
|
||||
return *this >> (bigint::tmp = i).get_ui();
|
||||
}
|
||||
|
||||
|
||||
template<int X, int L>
|
||||
gfp_<X, L> gfp_<X, L>::invert() const
|
||||
{
|
||||
gfp_ res;
|
||||
Inv(res.a, a, ZpD);
|
||||
return res;
|
||||
}
|
||||
|
||||
template<int X, int L>
|
||||
gfp_<X, L> gfp_<X, L>::sqrRoot()
|
||||
{
|
||||
|
||||
@@ -50,8 +50,7 @@ void gfpvar::init_field(bigint prime, bool montgomery)
|
||||
{
|
||||
ZpD.init(prime, montgomery);
|
||||
if (ZpD.get_t() > N_LIMBS)
|
||||
throw wrong_gfp_size("gfpvar too small for modulus. "
|
||||
"Maybe change MAX_MOD_SZ to " + to_string(ZpD.get_t() * 2));
|
||||
throw wrong_gfp_size("gfpvar", prime, "MAX_MOD_SZ", ZpD.get_t() * 2);
|
||||
}
|
||||
|
||||
void gfpvar::init_default(int lgp, bool montgomery)
|
||||
@@ -76,6 +75,16 @@ void gfpvar::generate_setup<Share<gfpvar>>(string prep_data_prefix,
|
||||
generate_prime_setup<Share<gfpvar>>(prep_data_prefix, nplayers, lgp);
|
||||
}
|
||||
|
||||
void gfpvar::check_setup(string dir)
|
||||
{
|
||||
::check_setup(dir, pr());
|
||||
}
|
||||
|
||||
void gfpvar::write_setup(string dir)
|
||||
{
|
||||
write_online_setup(dir, pr());
|
||||
}
|
||||
|
||||
gfpvar::gfpvar()
|
||||
{
|
||||
}
|
||||
@@ -148,9 +157,7 @@ gfpvar gfpvar::operator *(const gfpvar& other) const
|
||||
|
||||
gfpvar gfpvar::operator /(const gfpvar& other) const
|
||||
{
|
||||
gfpvar tmp;
|
||||
tmp.invert(other);
|
||||
return *this * tmp;
|
||||
return *this * other.invert();
|
||||
}
|
||||
|
||||
gfpvar& gfpvar::operator +=(const gfpvar& other)
|
||||
@@ -191,9 +198,11 @@ void gfpvar::negate()
|
||||
*this = gfpvar() - *this;
|
||||
}
|
||||
|
||||
void gfpvar::invert(const gfpvar& other)
|
||||
gfpvar gfpvar::invert() const
|
||||
{
|
||||
Inv(a, other.a, ZpD);
|
||||
gfpvar res;
|
||||
Inv(res.a, a, ZpD);
|
||||
return res;
|
||||
}
|
||||
|
||||
gfpvar gfpvar::sqrRoot() const
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user