Files
MP-SPDZ/FHEOffline/Verifier.cpp

133 lines
3.3 KiB
C++

#include "Verifier.h"
#include "FHE/P2Data.h"
#include "Math/Z2k.hpp"
#include "Math/modp.hpp"
template <class FD>
Verifier<FD>::Verifier(Proof& proof, const FD& FieldD) :
P(proof), FieldD(FieldD)
{
#ifdef LESS_ALLOC_MORE_MEM
z.resize(proof.phim);
z.allocate_slots(bigint(1) << proof.B_plain_length);
t.resize(3, proof.phim);
t.allocate_slots(bigint(1) << proof.B_rand_length);
#endif
}
template <class T, class FD, class S>
bool Check_Decoding(const Plaintext<T,FD,S>& AE,bool Diag)
{
// // Now check decoding z[i]
// if (!AE.to_type(0))
// { cout << "Fail Check 4 " << endl;
// return false;
// }
if (Diag && !AE.is_diagonal())
{ cout << "Fail Check 5 " << endl;
return false;
}
return true;
}
template <>
bool Check_Decoding(const vector<Proof::bound_type>& AE, bool Diag, const FFT_Data&)
{
if (Diag)
{
for (size_t i = 1; i < AE.size(); i++)
if (AE[i] != 0)
return false;
}
return true;
}
template <>
bool Check_Decoding(const vector<Proof::bound_type>& AE, bool Diag, const P2Data& p2d)
{
if (Diag)
{
Plaintext_<P2Data> tmp(p2d);
for (size_t i = 0; i < AE.size(); i++)
tmp.set_coeff(i, AE[i].get_limb(0) % 2);
return tmp.is_diagonal();
}
return true;
}
template <class FD>
void Verifier<FD>::Stage_2(
AddableVector<Ciphertext>& c,octetStream& ciphertexts,
octetStream& cleartexts,
const FHE_PK& pk,bool binary)
{
unsigned int i, V;
c.unpack(ciphertexts, pk);
if (c.size() != P.U)
throw length_error("number of received ciphertexts incorrect");
// Now check the encryptions are correct
Ciphertext d1(pk.get_params()), d2(pk.get_params());
Random_Coins rc(pk.get_params());
ciphertexts.get(V);
if (V != P.V)
throw length_error("number of received commitments incorrect");
cleartexts.get(V);
if (V != P.V)
throw length_error("number of received cleartexts incorrect");
for (i=0; i<V; i++)
{
z.unpack(cleartexts);
t.unpack(cleartexts);
if (!P.check_bounds(z, t, i))
throw runtime_error("preimage out of bounds");
d1.unpack(ciphertexts);
P.apply_challenge(i, d1, c, pk);
rc.assign(t[0], t[1], t[2]);
pk.encrypt(d2,z,rc);
if (!(d1 == d2))
{ cout << "Fail Check 6 " << i << endl;
throw runtime_error("ciphertexts don't match");
}
if (!Check_Decoding(z,P.get_diagonal(),FieldD))
{ cout << "\tCheck : " << i << endl;
throw runtime_error("cleartext isn't diagonal");
}
if (binary && !z.is_binary())
{
cout << "Not binary " << i << endl;
throw runtime_error("cleartext isn't binary");
}
}
}
/* This is the non-interactive version using the ROM
*/
template <class FD>
void Verifier<FD>::NIZKPoK(AddableVector<Ciphertext>& c,
octetStream& ciphertexts, octetStream& cleartexts,
const FHE_PK& pk,
bool binary)
{
P.set_challenge(ciphertexts);
Stage_2(c,ciphertexts,cleartexts,pk,binary);
if (P.top_gear)
{
assert(not P.get_diagonal());
assert(not binary);
c += c;
}
}
template class Verifier<FFT_Data>;
template class Verifier<P2Data>;