data61/MP-SPDZ

Generating edabits over GFp

Closed this issue · 2 comments

Hi Marcel,

How would I modify the below code to generate edabits over a prime field? The following code compiles for T = Spdz2k<64,64>

template<class T>
void run(char** argv)
    {
    // reduce batch size for testing
    OnlineOptions::singleton.bucket_size = 5;
    OnlineOptions::singleton.batch_size = 10000;

    // set up networking on localhost
    int my_number = atoi(argv[1]);
    int n_parties = atoi(argv[2]);
    int port_base = 9999;
    Names N(my_number, n_parties, "localhost", port_base);
    PlainPlayer P(N);

    // protocol setup (domain, MAC key if needed etc)
    MixedProtocolSetup<T> setup(P);

    // set of protocols (bit_input, multiplication, output)
    MixedProtocolSet<T> set(P, setup);
    auto& output = set.output;
    auto& bit_output = set.binary.output;
    auto& prep = set.preprocessing;

    int n_bits = 64;
    edabit<T> eb;
    
    // Generate edaBits
    prep.get_edabit_no_count(false, n_bits, eb);

    // Output binary part
    bit_output.init_open(P, n_bits);
    for (int i = 0; i < n_bits; i++) {
        bit_output.prepare_open(eb.second[i]);
    }
    bit_output.exchange(P);
    typename T::clear x;
    for (int i = 0; i < n_bits; i++) {
        x += typename T::clear(bit_output.finalize_open()) << i;
    }
    cout << "edabit B: " << x << endl;

    // Output arithmetic part
      output.init_open(P, 1);
      output.prepare_open(eb.first);
      output.exchange(P);
      cout << "edabit A: " << output.finalize_open() << endl;
  
      set.check();
}

However, I'm unable to get it to work for Mascot or regular SPDZ over a prime.

What do mean by unable getting it to work? Are there any error messages or other unexpected behaviour? What is the complete code and the commands you've used?

I was getting an error related to a power_of_two function being called in ShuffleSacrifice but I realized I was doing the protocol setup incorrectly. I got it to work, here is the full code for anyone else's reference and I'm closing the issue.

#define VERBOSE_DEBUG_PRINT

#include "Protocols/ProtocolSet.h"

#include "Machines/SPDZ.hpp"
#include "Machines/SPDZ2k.hpp"
#include "Machines/Semi2k.hpp"
#include "Math/gfp.hpp"
#include "Machines/ShamirMachine.hpp"

template<class T>
void run(char** argv, int prime_length);

int main(int argc, char** argv)
{
    // bit length of prime
    const int prime_length = 128;
    // compute number of 64-bit words needed
    const int n_limbs = (prime_length + 63) / 64;
    // need player number and number of players
    if (argc < 3)
    {
        cerr << "Usage: " << argv[0]
                << "<my number: 0/1/...> <total number of players> [protocol]"
                << endl;
        exit(1);
    }

    string protocol = "SPDZ2k";
    if (argc > 3)
        protocol = argv[3];

    if (protocol == "SPDZ2k")
        run<Spdz2kShare<64, 64>>(argv, 0);
    else if (protocol == "Semi2k")
        run<Semi2kShare<64>>(argv, 0);
    else if (protocol == "MASCOT")
        run<Share<gfp_<0, n_limbs>>>(argv, prime_length);
    else
    {
        cerr << "Unknown protocol: " << protocol << endl;
        exit(1);
    }
}

template<class T>
void run(char** argv, int prime_length)
{
    // reduce batch size
    // OnlineOptions::singleton.bucket_size = 5;
    OnlineOptions::singleton.batch_size = 10000;

    // set up networking on localhost
    int my_number = atoi(argv[1]);
    int n_parties = atoi(argv[2]);
    int port_base = 9999;
    Names N(my_number, n_parties, "localhost", port_base);
    // CryptoPlayer P(N);
    PlainPlayer P(N);

    // protocol setup (domain, MAC key if needed etc)
    MixedProtocolSetup<T> setup(P, prime_length);

    // set of protocols (bit_input, multiplication, output)
    MixedProtocolSet<T> set(P, setup);
    auto& output = set.output;
    // auto& bit_input = set.binary.input;
    // auto& bit_protocol = set.binary.protocol;
    auto& bit_output = set.binary.output;
    auto& prep = set.preprocessing;

    int n_bits = 128;
    edabit<T> eb;
    
    prep.get_edabit_no_count(true, n_bits, eb);

    bit_output.init_open(P, n_bits);
    for (int i = 0; i < n_bits; i++) {
        bit_output.prepare_open(eb.second[i]);
    }
    bit_output.exchange(P);
    typename T::clear x;
    for (int i = 0; i < n_bits; i++) {
        x += typename T::clear(bit_output.finalize_open()) << i;
    }
    cout << "edabit B compose: " << x << endl;

    output.init_open(P, 1);
    output.prepare_open(eb.first);
    output.exchange(P);

    cout << "edabit A: " << output.finalize_open() << endl;

    set.check();
}