cryptobiu / libscapi

Comprehensive Open Source Library for Secure Multiparty Computation
MIT License
180 stars 66 forks source link

Incorrect output from BooleanCircuit (parsed from text file) #45

Closed basitkhurram closed 5 years ago

basitkhurram commented 6 years ago

I've tried creating a basic boolean circuit and evaluating it.

The circuit is as follows (the comments are included for readability, the actual text file does not contain the comments, as I've found that the comments throw the parser off):

// addition_circuit.txt

1     // One gate
1     // One party

1     // First party
2     // Two inputs
0     // Input labeled as "0"
1     // Input labeled as "1"

1     // One output
2     // Output labeled as "2"

// First gate
2     // Two inputs
1     // One output
0     // Input labeled as "0"
1     // Input labeled as "1"
2     // Output labeled as "2"
0001  // Truth table representing "AND" 

Regardless of the input I set, I seem to get "0" as the output.

Here is the code that I am using

#include <iostream>
#include "../include/circuits/BooleanCircuits.hpp"

using namespace std;

int main() {

    BooleanCircuit bc(new scannerpp::File("addition_circuit.txt"));

        // Code to confirm that the gate has been parsed correctly from the text file.
    for (Gate gate : bc.getGates()) {
        cout << "\nGate is ";
        for (int bit : gate.getTruthTable()) {
            cout << bit;
        }
    }

        // Iterate over all combinations of inputs
    for (int i0 = 0; i0 < 2; i0++) {
        for (int i1 = 0; i1 < 2; i1++) {
            map<int, Wire> presetInputWires = { { 0, Wire(i0) },
                                                            { 1, Wire(i1) } };
            bc.setInputs(presetInputWires, 1);
            auto bc_result = bc.compute();
            int result = bc_result[2].getValue();
            std::cout << "\n\nInputs are " << i0 << " and " << i1;
            std::cout << "\nOutput is " << result << endl;
        }
    }
    return 0;
}   

Is there something obvious that I am missing?

I should add that I seem to get the correct results when instantiating the boolean circuit using Gate objects (as opposed to using a text file).

basitkhurram commented 6 years ago

I've found two issues with the above.

First, it looks like you can't set a party's input more than once, for any given instance of a BooleanCircuit. Well, you could try, but the inputs won't change.

bc.setInputs(presetInputWires1, 1) // set party 1's inputs to presetInputWires1.
bc.setInputs(presetInputWires2, 1) // try to set party 1's inputs to presetInputWires2.

// No error is thrown, but it looks like the second call to setInputs is essentially ignored.
basitkhurram commented 6 years ago

Second, I tried building a simple circuit using Gate objects and then writing the circuit to a text file:

// testSimpleCircuitOutput.cpp

#include "../include/circuits/BooleanCircuits.hpp"

int main()  {
    Gate g1(1, { 0, 1, 1, 1 }, { 0, 1 }, { 2 });            // This is a basic OR gate with two inputs and one output.
    vector<int> outputs = { 2 };
    BooleanCircuit bc({ g1 }, outputs, { {0, 1} });   // This is a basic boolean circuit with one party. 
    bc.write("circuit_test_output.txt");
    return 0;
}

Writing the circuit created above gives the following text file.

// circuit_test_output.txt

1      // Number of gates
1      // Number of parties

1 2    // Party number, number of inputs
0      // Input label "0"
1      // Input label "1"

1 1    // **The inconsistency appears in this line**. According to the docs, there should only be one "1" here, to indicate the number of outputs.
2      // Output label "2"

// First gate. 
2 1 0 1 2 0111      // Two inputs, one output, inputs labelled "0" and "1", output labelled "2", use an OR gate.

The circuit, as described in the text file, is inconsistent with how circuits are described here (http://biulibscapi.readthedocs.io/en/latest/circuits.html). This issue seems to be specific to working with one party. Perhaps it is intentional behaviour, but the documents don't seem to indicate that that is the case.

Edit: Ah, the circuit's format seems to match the format expected for a "multy party circuit" when only one party is used.

moriyaw commented 5 years ago

Hi,

Sorry for the late response.

In case that this is still relevant - I fixed the setInput function. Now you can call it multiple times and it will change the inputs. The issue with the file is not a bug. Our approach is that if the circuit contain two parties then the circuit file should be in the two-party format. Otherwise, it should be in the multi-party format. (Also, there is no point to use a circuit for only one party so this option wasn't taken into account)

Is that was helpful?