Visa-Research / volepsi

Efficient Private Set Intersection base on VOLE
MIT License
98 stars 32 forks source link

bug for networkSocketExample.h #59

Closed Fix3dP0int closed 5 months ago

Fix3dP0int commented 6 months ago

Hello, doctor! I found the bug when I wrote the code to perform the PSI of big set size like networkSocketExample.h instead of small set size. And I just modify the source code networkSocketExample.h. It happens somthing wrong.

The code modified by myself:

        auto ns = 1 << cmd.getOr("senderSize", 20ull);
        auto nr = 1 << cmd.getOr("receiverSize", 20ull);

And it return:

[root@devstack volepsi]# ./out/build/linux/frontend/frontend -sender -r 0 & ./out/build/linux/frontend/frontend -recver -r 1
[1] 2998976
connecting as client at ip localhost:1212
connecting as server at ip localhost:1212
connected
connected
sender start
recver start
sender done, 421022ms
Socket was destroyed with pending operations. terminate() is being called. Await Socket::flush() before the destructor is called. This will ensure thatall pending operations complete. /root/volepsi/out/install/linux/include/coproto/Socket/SocketScheduler.h:709
terminate called without an active exception
End of file
[1]+  Aborted                 (core dumped) ./out/build/linux/frontend/frontend -sender -r 0

I don't know whether I do something in error.

Fix3dP0int commented 6 months ago

Maybe it needs some operations like join()?

ladnir commented 6 months ago

Add sync_wait(sock.flush()); to the end.

Fix3dP0int commented 6 months ago

Thanks. It works. And I have another questions: I want to wrap the encoding function and decoding funtion about baxos that has simpler interface:

void encode(const std::vector<block>& key, const std::vector<block>& value, std::vector<block>& OKVStable){
    u64 n = key.size();
    u64 w = 3, ssp = 40, nt = 0, binSize = 1 << 15;
    auto dt = PaxosParam::GF128;
    u64 baxosSize;
    {
        Baxos paxos;
        paxos.init(n, binSize, w, ssp, dt, oc::ZeroBlock);
        baxosSize = paxos.size();
    }
    OKVStable.resize(baxosSize);
    Baxos paxos;
    paxos.init(n, binSize, w, ssp, dt, block(0, 0));
    paxos.solve<block>(key, value, OKVStable, nullptr, nt);
}

void decode(const std::vector<block>& key, std::vector<block>& value, const std::vector<block>& OKVStable){
    u64 n = key.size();
    u64 w = 3, ssp = 40, nt = 0, binSize = 1 << 15;
    auto dt = PaxosParam::GF128;
    u64 baxosSize;
    {
        Baxos paxos;
        paxos.init(n, binSize, w, ssp, dt, oc::ZeroBlock);
        baxosSize = paxos.size();
    }
    Baxos paxos;
    paxos.init(n, binSize, w, ssp, dt, block(0, 0));
    paxos.decode<block>(key, value, OKVStable, nt);
}

void toybaxostest(const oc::CLP& cmd){
    auto n = 4;
    auto ssp = cmd.getOr("ssp", 40ull);
    auto mal = cmd.isSet("malicious");
    // The vole type, default to expand accumulate.
    auto type = oc::DefaultMultType;
#ifdef ENABLE_INSECURE_SILVER
    type = cmd.isSet("useSilver") ? oc::MultType::slv5 : type;
#endif
#ifdef ENABLE_BITPOLYMUL
    type = cmd.isSet("useQC") ? oc::MultType::QuasiCyclic : type;
#endif
    // use fewer rounds of communication but more computation.
    auto useReducedRounds = cmd.isSet("reducedRounds");

    u64 w = 3, nt = 0, binSize = 1 << 15;
    auto dt = PaxosParam::GF128;
    u64 baxosSize;
    {
        Baxos paxos;
        paxos.init(n, binSize, w, ssp, dt, oc::ZeroBlock);
        baxosSize = paxos.size();
    }
    std::vector<block> Set(n);
    std::vector<block> Value(n);
    std::vector<block> OKVSTable(baxosSize);
    Set[0] = (block) 100;
    Set[1] = (block) 99;
    Set[2] = (block) 98;
    Set[3] = (block) 97;
    block AESKey;
    AESKey = (block) 123456789;
    AES AES;
    AES.setKey(AESKey);
    AES.ecbEncBlocks(Set.data(), Set.size(), Value.data());
    encode(Set, Value, OKVSTable);
    std::cout << "encode OKVS: ";
    for (auto i = 0; i < OKVSTable.size(); ++i){
        std::cout << OKVSTable[i] << " ";
    }
}
[root@devstack volepsi]# ./out/build/linux/frontend/frontend -useSilver
encode OKVS: 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 b8ea727110d3342d2ebcfa78f6b03abe e76e69e84999f89a4b95070a7f44941b 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 89a2c3164ccc86888b0978a1ebdaa53f a0138bec697a132c86bbee9913251400 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000

It can decode correctly. But It happens many zeros in OKVSTable. I don't understand the details of baxos. Is it normal? Can I encode or decode just using above functions?

ladnir commented 6 months ago

Yeah, for small sized I'd expect many empty positions. For larger it should be more filled in.

Fix3dP0int commented 6 months ago

OK. It‘s helpful to me. Thank you again! There is a new question:

        if (pIDx == t - 2){
            // ...
            // do something 
            // ...
            ip2 = "localhost:" + std::to_string(2 * 1212 + t - 2);
            std::cout << "party " << pIDx << "PSI start" << std::endl;
            PSIChlClient = coproto::asioConnect(ip2, 0);
            volePSI::RsPsiSender sender;
            sender.setMultType(type);
            sender.init(n, n, ssp, oc::sysRandomSeed(), mal, 1, useReducedRounds);
            std::cout << pIDx << "PSI init" << std::endl;
            macoro::sync_wait(sender.run(Value[t - 2], PSIChlClient));
            macoro::sync_wait(PSIChlClient.flush());
            std::cout << "party " << pIDx << "PSI send done" << std::endl;
        }
        if (pIDx == t - 1)
        {
            // ...
            // do something
            // ...
            volePSI::RsPsiReceiver recevier;
            std::cout << "party " << pIDx << " decode done" << std::endl;
            std::string ip2 = "localhost:" + std::to_string(2 * 1212 + t - 2);
            PSIChlServer = coproto::asioConnect(ip2, 1);
            recevier.setMultType(type);
            recevier.init(n, n, ssp, oc::sysRandomSeed(), mal, 1, useReducedRounds);
            std::cout << pIDx << "PSI init" << std::endl;
            macoro::sync_wait(recevier.run(Value[pIDx], PSIChlServer));

            std::cout << "mIntersectionSize:" << recevier.mIntersection.size() << std::endl;
            macoro::sync_wait(PSIChlServer.flush());
            std::cout << "PSI done" << std::endl;
        }

This error is happening when n is set larger. But I tested it for small size like 4. It is OK. I thought it is because of not adding macoro::sync_wait(PSIChlServer.flush());. But even if I add it, it doesn't work. Please give me some suggestions. Thank you! Actually, I'm writing codes for multi-PSI. The hidden codes did something to get the information. And finally it needs two parties to perform PSI. Besides, I use the method like macoro::sync_wait(Client.send(message)); and macoro::sync_wait(Server.recv(message)); to communicate among parties. Here is the error information:

Paxos error, Duplicate keys were detected at idx
                                                  , key=02bb8b0009284d15452b43289b61be12
Socket was destroyed with pending operations. terminate() is being called. Await Socket::flush() before the destructor is called. This will ensure thatall pending operations complete. /root/volepsi/out/install/linux/include/coproto/Socket/SocketScheduler.h:709
terminate called without an active exception
start.sh: line 8: 3158551 Segmentation fault      (core dumped) ./out/build/linux/frontend/frontend -t $t -n $n -p $p
start.sh: line 8: 3158552 Aborted                 (core dumped) ./out/build/linux/frontend/frontend -t $t -n $n -p $p
Fix3dP0int commented 6 months ago

I perhaps find the reason for the error.If I use

         for (auto i = 0; i < t; ++i)
             prng.get(Set[i].data(), Set[i].size());

to generate the set of parties, the error will happen. But if I use

        for (auto i = 0; i < t; ++i){
            for (auto j = 0; j < n; ++j){
                Set[i][j] = (block) (100 + j);
                if (j == n - 1)
                    Set[i][j] = (block) pIDx;
            }
        }

instead of prng. It will success. Maybe it is because the prng have impact on PSI?

ladnir commented 6 months ago

The socket error is because the socket is trying to send data when you destroy it. Like when it goes out of scope. I told you how to fix it.

It looks like you have some other error. You posted it

Paxos error, Duplicate keys were detected at idx
                                                  , key=02bb8b0009284d15452b43289b61be12

Sounds like you are inputting duplicate keys.....

Fix3dP0int commented 6 months ago

OK. I have fixed it. Thanks.

Fix3dP0int commented 5 months ago

Hi. Please forgive me to bother you again. I reproduce below error. Could you tell me what "duplicate keys" means actually? It will help me fix it. And I just use some bigger data as input (some 128-bits intergers), then it will happen. Does the code support 128-bits data?

Paxos error, Duplicate keys were detected at idx
                                                  , key=02bb8b0009284d15452b43289b61be12
ladnir commented 5 months ago

Two of your input values are the same. It prints the value of the duplicate. You are not allowed to have duplicate keys.

Fix3dP0int commented 5 months ago

OK. I used to misunderstand the meaning of key before. Now I can get it. Thanks!!!