mirror of
https://github.com/encryptogroup/PSI.git
synced 2024-03-22 13:30:44 +08:00
Added test routines
This commit is contained in:
parent
849f790167
commit
70d49f1871
6
Makefile
6
Makefile
|
@ -72,6 +72,12 @@ bench:
|
||||||
demo:
|
demo:
|
||||||
${CC} -o demo.exe ${SRC}/mains/psi_demo.cpp ${OBJECTS_DHPSI} ${OBJECTS_OTPSI} ${OBJECTS_NAIVE} ${OBJECTS_SERVERAIDED} ${OBJECTS_UTIL} ${OBJECTS_HASHING} ${OBJECTS_CRYPTO} ${OBJECTS_OT} ${OBJECTS_MIRACL} ${CFLAGS} ${DEBUG_OPTIONS} ${LIBRARIES} ${MIRACL_LIB} ${INCLUDE} ${COMPILER_OPTIONS}
|
${CC} -o demo.exe ${SRC}/mains/psi_demo.cpp ${OBJECTS_DHPSI} ${OBJECTS_OTPSI} ${OBJECTS_NAIVE} ${OBJECTS_SERVERAIDED} ${OBJECTS_UTIL} ${OBJECTS_HASHING} ${OBJECTS_CRYPTO} ${OBJECTS_OT} ${OBJECTS_MIRACL} ${CFLAGS} ${DEBUG_OPTIONS} ${LIBRARIES} ${MIRACL_LIB} ${INCLUDE} ${COMPILER_OPTIONS}
|
||||||
|
|
||||||
|
test:
|
||||||
|
${CC} -o test.exe ${SRC}/mains/test_psi.cpp ${OBJECTS_DHPSI} ${OBJECTS_OTPSI} ${OBJECTS_NAIVE} ${OBJECTS_SERVERAIDED} ${OBJECTS_UTIL} ${OBJECTS_HASHING} ${OBJECTS_CRYPTO} ${OBJECTS_OT} ${OBJECTS_MIRACL} ${CFLAGS} ${DEBUG_OPTIONS} ${LIBRARIES} ${MIRACL_LIB} ${INCLUDE} ${COMPILER_OPTIONS}
|
||||||
|
./test.exe -r 0 -t 10 &
|
||||||
|
./test.exe -r 1 -t 10
|
||||||
|
|
||||||
|
|
||||||
cuckoo:
|
cuckoo:
|
||||||
${CC} -o cuckoo.exe ${SRC}/mains/cuckoo_analysis.cpp ${OBJECTS_UTIL} ${OBJECTS_HASHING} ${OBJECTS_CRYPTO} ${OBJECTS_MIRACL} ${CFLAGS} ${DEBUG_OPTIONS} ${LIBRARIES} ${MIRACL_LIB} ${INCLUDE} ${COMPILER_OPTIONS}
|
${CC} -o cuckoo.exe ${SRC}/mains/cuckoo_analysis.cpp ${OBJECTS_UTIL} ${OBJECTS_HASHING} ${OBJECTS_CRYPTO} ${OBJECTS_MIRACL} ${CFLAGS} ${DEBUG_OPTIONS} ${LIBRARIES} ${MIRACL_LIB} ${INCLUDE} ${COMPILER_OPTIONS}
|
||||||
|
|
||||||
|
|
19
README.md
19
README.md
|
@ -68,6 +68,25 @@ These commands will run the naive hashing protocol and compute the intersection
|
||||||
|
|
||||||
For further information about the program options, run ```./demo.exe -h```.
|
For further information about the program options, run ```./demo.exe -h```.
|
||||||
|
|
||||||
|
### Testing the Protocols
|
||||||
|
|
||||||
|
The protocols will automatically be tested on randomly generated data when invoking:
|
||||||
|
```
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
WARNING: Some tests can still fail since the code is currently being debugged.
|
||||||
|
|
||||||
|
### Generating Random Email Adresses
|
||||||
|
|
||||||
|
Further random email adresses can be generated by navigating to `/sample_sets/emailgenerator/` and invoking:
|
||||||
|
|
||||||
|
```
|
||||||
|
./emailgenerator.py "number_of_emails"
|
||||||
|
```
|
||||||
|
|
||||||
|
The generator uses the first names, family names, and email providers listed in the corresponding files in `sample_sets/emailgenerator/` as base for the generation.
|
||||||
|
|
||||||
### References
|
### References
|
||||||
|
|
||||||
[1] B. Pinkas, T. Schneider, M. Zohner. Faster Private Set Intersection Based on OT Extension. USENIX Security 2014: 797-812. Full version available at http://eprint.iacr.org/2014/447.
|
[1] B. Pinkas, T. Schneider, M. Zohner. Faster Private Set Intersection Based on OT Extension. USENIX Security 2014: 797-812. Full version available at http://eprint.iacr.org/2014/447.
|
||||||
|
|
|
@ -165,7 +165,7 @@ inline void gen_cuckoo_entry(uint8_t* in, cuckoo_entry_ctx* out, hs_t* hs, uint3
|
||||||
out->eleid = ele_id;
|
out->eleid = ele_id;
|
||||||
|
|
||||||
#ifndef TEST_UTILIZATION
|
#ifndef TEST_UTILIZATION
|
||||||
out->val = (uint8_t*) malloc(hs->outbytelen);
|
out->val = (uint8_t*) calloc(hs->outbytelen, sizeof(uint8_t));
|
||||||
#endif
|
#endif
|
||||||
hashElement(in, out->address, out->val, hs);
|
hashElement(in, out->address, out->val, hs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ static const uint32_t SELECT_BITS_INV[33] = \
|
||||||
0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000, 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000, \
|
0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000, 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000, \
|
||||||
0x00000000 };
|
0x00000000 };
|
||||||
|
|
||||||
|
static const uint8_t BYTE_SELECT_BITS_INV[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01};
|
||||||
|
|
||||||
//Init the values for the hash function
|
//Init the values for the hash function
|
||||||
static void init_hashing_state(hs_t* hs, uint32_t nelements, uint32_t inbitlen, uint32_t nbins,
|
static void init_hashing_state(hs_t* hs, uint32_t nelements, uint32_t inbitlen, uint32_t nbins,
|
||||||
|
@ -168,8 +169,26 @@ inline void hashElement(uint8_t* element, uint32_t* address, uint8_t* val, hs_t*
|
||||||
*((uint32_t*) val) = R;
|
*((uint32_t*) val) = R;
|
||||||
//TODO copy remaining bits
|
//TODO copy remaining bits
|
||||||
|
|
||||||
if(hs->outbytelen >= sizeof(uint32_t))
|
//if(hs->outbytelen >= sizeof(uint32_t))
|
||||||
memcpy(val + (sizeof(uint32_t) - hs->addrbytelen), element + sizeof(uint32_t), hs->outbytelen - sizeof(uint32_t));
|
if(hs->outbitlen + hs->addrbitlen >= sizeof(uint32_t) * 8) {
|
||||||
|
//memcpy(val + (sizeof(uint32_t) - hs->addrbytelen), element + sizeof(uint32_t), hs->outbytelen - (sizeof(uint32_t) - hs->addrbytelen));
|
||||||
|
memcpy(val + (sizeof(uint32_t) - (hs->addrbitlen >>3)), element + sizeof(uint32_t), hs->outbytelen - (sizeof(uint32_t) - (hs->addrbitlen >>3)));
|
||||||
|
|
||||||
|
//cout << "Element: "<< (hex) << (uint32_t) val[hs->outbytelen-1] << ", " << (uint32_t) (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03])
|
||||||
|
// << ", " << (uint32_t) (val[hs->outbytelen-1] & (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03]) )<< (dec) << " :";
|
||||||
|
|
||||||
|
val[hs->outbytelen-1] &= (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03]);
|
||||||
|
|
||||||
|
/*for(i = 0; i < hs->inbytelen; i++) {
|
||||||
|
cout << (hex) << (uint32_t) element[i];
|
||||||
|
}
|
||||||
|
cout << ", ";
|
||||||
|
for(i = 0; i < hs->outbytelen; i++) {
|
||||||
|
cout << (hex) << (uint32_t) val[i];
|
||||||
|
}
|
||||||
|
cout << (dec) << endl;*/
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
//cout << "Address for hfid = " << hfid << ": " << *address << ", L = " << L << ", R = " << R << endl;
|
//cout << "Address for hfid = " << hfid << ": " << *address << ", L = " << L << ", R = " << R << endl;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ void *gen_entries(void *ctx_tmp) {
|
||||||
uint32_t i, inbytelen, *address;
|
uint32_t i, inbytelen, *address;
|
||||||
|
|
||||||
address = (uint32_t*) malloc(NUM_HASH_FUNCTIONS * sizeof(uint32_t));
|
address = (uint32_t*) malloc(NUM_HASH_FUNCTIONS * sizeof(uint32_t));
|
||||||
tmpbuf = (uint8_t*) malloc(ceil_divide(ctx->hs->outbitlen, 8)); //for(i = 0; i < NUM_HASH_FUNCTIONS; i++) {
|
tmpbuf = (uint8_t*) calloc(ceil_divide(ctx->hs->outbitlen, 8), sizeof(uint8_t)); //for(i = 0; i < NUM_HASH_FUNCTIONS; i++) {
|
||||||
// tmpbuf[i] = (uint8_t*) malloc(ceil_divide(ctx->hs->outbitlen, 8));
|
// tmpbuf[i] = (uint8_t*) malloc(ceil_divide(ctx->hs->outbitlen, 8));
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -132,7 +132,10 @@ inline void insert_element(sht_ctx* table, uint8_t* element, uint32_t* address,
|
||||||
}
|
}
|
||||||
tmp_bin->nvals++;
|
tmp_bin->nvals++;
|
||||||
//TODO: or simply allocate a bigger block of memory: table->maxbinsize * 2, left out for efficiency reasons
|
//TODO: or simply allocate a bigger block of memory: table->maxbinsize * 2, left out for efficiency reasons
|
||||||
assert(tmp_bin->nvals < table->maxbinsize);
|
if(tmp_bin->nvals == table->maxbinsize) {
|
||||||
|
increase_max_bin_size(table, hs->outbytelen);
|
||||||
|
}
|
||||||
|
//assert(tmp_bin->nvals < table->maxbinsize);
|
||||||
/*cout << "Inserted into bin: " << address << ": " << (hex);
|
/*cout << "Inserted into bin: " << address << ": " << (hex);
|
||||||
for(uint32_t j = 0; j < table->outbytelen; j++) {
|
for(uint32_t j = 0; j < table->outbytelen; j++) {
|
||||||
cout << (unsigned int) tmpbuf[j];
|
cout << (unsigned int) tmpbuf[j];
|
||||||
|
@ -142,7 +145,6 @@ inline void insert_element(sht_ctx* table, uint8_t* element, uint32_t* address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_hash_table(sht_ctx* table, uint32_t nelements, hs_t* hs) {
|
void init_hash_table(sht_ctx* table, uint32_t nelements, hs_t* hs) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
@ -176,3 +178,15 @@ void free_hash_table(sht_ctx* table) {
|
||||||
//3. free the actual table
|
//3. free the actual table
|
||||||
//free(table);
|
//free(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void increase_max_bin_size(sht_ctx* table, uint32_t valbytelen) {
|
||||||
|
uint32_t new_maxsize = table->maxbinsize * 2;
|
||||||
|
uint8_t* tmpvals;
|
||||||
|
for(uint32_t i = 0; i < table->nbins; i++) {
|
||||||
|
tmpvals = table->bins[i].values;
|
||||||
|
table->bins[i].values = (uint8_t*) malloc(new_maxsize * valbytelen);
|
||||||
|
memcpy(table->bins[i].values, tmpvals, table->bins[i].nvals * valbytelen);
|
||||||
|
free(tmpvals);
|
||||||
|
}
|
||||||
|
table->maxbinsize = new_maxsize;
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ uint8_t* simple_hashing(uint8_t* elements, uint32_t neles, uint32_t bitlen, uint
|
||||||
//routine for generating the entries, is invoked by the threads
|
//routine for generating the entries, is invoked by the threads
|
||||||
void *gen_entries(void *ctx);
|
void *gen_entries(void *ctx);
|
||||||
void init_hash_table(sht_ctx* table, uint32_t nelements, hs_t* hs);
|
void init_hash_table(sht_ctx* table, uint32_t nelements, hs_t* hs);
|
||||||
|
void increase_max_bin_size(sht_ctx* table, uint32_t valbytelen);
|
||||||
void free_hash_table(sht_ctx* table);
|
void free_hash_table(sht_ctx* table);
|
||||||
inline void insert_element(sht_ctx* table, uint8_t* element, uint32_t* address, uint8_t* tmpbuf, hs_t* hs);
|
inline void insert_element(sht_ctx* table, uint8_t* element, uint32_t* address, uint8_t* tmpbuf, hs_t* hs);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,243 @@
|
||||||
* Author: mzohner
|
* Author: mzohner
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "test_psi.h"
|
||||||
|
|
||||||
|
int32_t main(int32_t argc, char** argv) {
|
||||||
|
string address="127.0.0.1";
|
||||||
|
uint32_t nelements, elebytelen, ntasks=1, nruns=1, symsecbits=128;
|
||||||
|
uint64_t rnd;
|
||||||
|
role_type role = (role_type) 0;
|
||||||
|
vector<CSocket> sockfd(ntasks);
|
||||||
|
uint16_t port=7766;
|
||||||
|
uint8_t* seed = (uint8_t*) malloc(AES_BYTES);
|
||||||
|
|
||||||
|
|
||||||
|
read_psi_test_options(&argc, &argv, &role, &nruns);
|
||||||
|
|
||||||
|
memcpy(seed, const_seed, AES_BYTES);
|
||||||
|
seed[0] = role;
|
||||||
|
crypto* crypt = new crypto(symsecbits, seed);
|
||||||
|
|
||||||
|
crypt->gen_rnd((uint8_t*) &rnd, sizeof(uint64_t));
|
||||||
|
srand((unsigned)rnd+time(0));
|
||||||
|
|
||||||
|
if(role == SERVER) {
|
||||||
|
listen(address.c_str(), port, sockfd.data(), ntasks);
|
||||||
|
} else {
|
||||||
|
for(uint32_t i = 0; i < ntasks; i++)
|
||||||
|
connect(address.c_str(), port, sockfd[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < nruns; i++) {
|
||||||
|
if(role == CLIENT) cout << "Running test on iteration " << i << std::flush;
|
||||||
|
nelements = rand() % (1<<12);
|
||||||
|
elebytelen = (rand() % 14) + 2;
|
||||||
|
test_psi_prot(role, sockfd.data(), nelements, elebytelen, crypt);
|
||||||
|
if(role == CLIENT) cout << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "All tests successfully passed" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t test_psi_prot(role_type role, CSocket* sock, uint32_t nelements,
|
||||||
|
uint32_t elebytelen, crypto* crypt) {
|
||||||
|
double epsilon=1.2;
|
||||||
|
uint32_t p_inter_size, n_inter_size, ot_inter_size, dh_inter_size, i, j, ntasks=1,
|
||||||
|
pnelements, nclients = 2;
|
||||||
|
uint8_t *elements, *pelements, *p_intersection, *n_intersection, *ot_intersection, *dh_intersection;
|
||||||
|
|
||||||
|
//if(protocol != TTP)
|
||||||
|
|
||||||
|
pnelements = set_up_parameters(role, nelements, &elebytelen, &elements, &pelements, sock[0], crypt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
p_inter_size = plaintext_intersect(nelements, pnelements, elebytelen, elements, pelements,
|
||||||
|
&p_intersection);
|
||||||
|
//cout << "Plaintext intersection computed " << endl;
|
||||||
|
if(role == CLIENT) cout << "." << std::flush;
|
||||||
|
|
||||||
|
n_inter_size = naivepsi(role, nelements, pnelements, elebytelen, elements, &n_intersection, crypt,
|
||||||
|
sock, ntasks);
|
||||||
|
//cout << "Naive intersection computed " << endl;
|
||||||
|
if(role == CLIENT) cout << "." << std::flush;
|
||||||
|
|
||||||
|
dh_inter_size = dhpsi(role, nelements, pnelements, elebytelen, elements, &dh_intersection, crypt,
|
||||||
|
sock, ntasks);
|
||||||
|
//cout << "DH intersection computed " << endl;
|
||||||
|
if(role == CLIENT) cout << "." << std::flush;
|
||||||
|
|
||||||
|
ot_inter_size = otpsi(role, nelements, pnelements, elebytelen, elements, &ot_intersection,
|
||||||
|
crypt, sock, ntasks, epsilon);
|
||||||
|
//cout << "OT intersection computed " << endl;
|
||||||
|
if(role == CLIENT) cout << "." << std::flush;
|
||||||
|
|
||||||
|
|
||||||
|
if(role == CLIENT) {
|
||||||
|
bool success = true;
|
||||||
|
success &= (p_inter_size == n_inter_size);
|
||||||
|
success &= (p_inter_size == dh_inter_size);
|
||||||
|
success &= (p_inter_size == ot_inter_size);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < p_inter_size * elebytelen; i++) {
|
||||||
|
success &= (p_intersection[i] == n_intersection[i]);
|
||||||
|
success &= (p_intersection[i] == dh_intersection[i]);
|
||||||
|
success &= (p_intersection[i] == ot_intersection[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!success) {
|
||||||
|
cout << "Error in tests for " << nelements << " and " << pnelements << " on " << elebytelen
|
||||||
|
<< " byte length: " << endl;
|
||||||
|
|
||||||
|
cout << "\t" << p_inter_size << " elements in verification intersection" << endl;
|
||||||
|
cout << "\t" << n_inter_size << " elements in naive intersection" << endl;
|
||||||
|
cout << "\t" << dh_inter_size << " elements in DH intersection" << endl;
|
||||||
|
cout << "\t" << ot_inter_size << " elements in OT intersection" << endl;
|
||||||
|
|
||||||
|
cout << "Plaintext intersection (" << p_inter_size << "): " << endl;
|
||||||
|
plot_set(p_intersection, p_inter_size, elebytelen);
|
||||||
|
cout << "Naive intersection (" << n_inter_size << "): " << endl;
|
||||||
|
plot_set(n_intersection, n_inter_size, elebytelen);
|
||||||
|
cout << "DH intersection (" << dh_inter_size << "): " << endl;
|
||||||
|
plot_set(dh_intersection, dh_inter_size, elebytelen);
|
||||||
|
cout << "OT intersection: (" << ot_inter_size << "): " << endl;
|
||||||
|
plot_set(ot_intersection, ot_inter_size, elebytelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p_inter_size > 0)
|
||||||
|
free(p_intersection);
|
||||||
|
if(n_inter_size > 0)
|
||||||
|
free(n_intersection);
|
||||||
|
if(dh_inter_size > 0)
|
||||||
|
free(dh_intersection);
|
||||||
|
if(ot_inter_size > 0)
|
||||||
|
free(ot_intersection);
|
||||||
|
|
||||||
|
assert(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
free(elements);
|
||||||
|
free(pelements);
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void plot_set(uint8_t* set, uint32_t neles, uint32_t elebytelen) {
|
||||||
|
for(uint32_t i = 0; i < neles; i++) {
|
||||||
|
cout << i << ": ";
|
||||||
|
for(uint32_t j = 0; j < elebytelen; j++) {
|
||||||
|
cout << setw(2) << setfill('0') << (hex) << (uint32_t) set[i*elebytelen+j];
|
||||||
|
}
|
||||||
|
cout << (dec) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t plaintext_intersect(uint32_t myneles, uint32_t pneles, uint32_t bytelen, uint8_t* myelements,
|
||||||
|
uint8_t* pelements, uint8_t** result) {
|
||||||
|
uint32_t intersect_size = 0, i, j;
|
||||||
|
uint64_t tmpkey = 0;
|
||||||
|
uint8_t *tmpval;
|
||||||
|
uint8_t** matches = (uint8_t**) malloc(sizeof(uint8_t*) * min(myneles, pneles));
|
||||||
|
uint32_t keylen = min((uint32_t) bytelen, (uint32_t) 8);
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
|
||||||
|
GHashTable *map= g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL, NULL);
|
||||||
|
for(i = 0; i < myneles; i++) {
|
||||||
|
memcpy(&tmpkey, myelements+i*bytelen, keylen);
|
||||||
|
g_hash_table_insert(map,(void*) &tmpkey, myelements+i*bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < pneles; i++) {
|
||||||
|
memcpy(&tmpkey, pelements+i*bytelen, keylen);
|
||||||
|
if(g_hash_table_lookup_extended(map, (void*) &tmpkey, NULL, (void**) &tmpval)) {
|
||||||
|
success = true;
|
||||||
|
if(bytelen > 8) {
|
||||||
|
for(j = 8; j < bytelen && success; j++) {
|
||||||
|
if(tmpval[j] != pelements[i*bytelen+j])
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(success) {
|
||||||
|
matches[intersect_size] = (uint8_t*) tmpval;
|
||||||
|
intersect_size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(intersect_size <= min(myneles, pneles));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = (uint8_t*) malloc(intersect_size * bytelen);
|
||||||
|
|
||||||
|
for(i = 0; i < intersect_size; i++) {
|
||||||
|
memcpy((*result) + i * bytelen, matches[i], bytelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(matches);
|
||||||
|
return intersect_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t set_up_parameters(role_type role, uint32_t myneles, uint32_t* mybytelen,
|
||||||
|
uint8_t** elements, uint8_t** pelements, CSocket& sock, crypto* crypt) {
|
||||||
|
|
||||||
|
uint32_t pneles, nintersections;
|
||||||
|
|
||||||
|
//Exchange meta-information and equalize byte-length
|
||||||
|
sock.Send(&myneles, sizeof(uint32_t));
|
||||||
|
sock.Receive(&pneles, sizeof(uint32_t));
|
||||||
|
|
||||||
|
if(role == SERVER) {
|
||||||
|
sock.Send(mybytelen, sizeof(uint32_t));
|
||||||
|
} else {
|
||||||
|
sock.Receive(mybytelen, sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
*elements = (uint8_t*) malloc(myneles * *mybytelen);
|
||||||
|
*pelements = (uint8_t*) malloc(pneles * *mybytelen);
|
||||||
|
|
||||||
|
crypt->gen_rnd(*elements, myneles * *mybytelen);
|
||||||
|
|
||||||
|
//Exchange elements for later check
|
||||||
|
if(role == SERVER) {
|
||||||
|
sock.Send(*elements, myneles * *mybytelen);
|
||||||
|
sock.Receive(*pelements, pneles * *mybytelen);
|
||||||
|
} else { //have the client use some of the servers values s.t. the intersection is not disjoint
|
||||||
|
sock.Receive(*pelements, pneles * *mybytelen);
|
||||||
|
nintersections = rand() % min(myneles, pneles);
|
||||||
|
for(uint32_t i = 0; i < nintersections; i++) {
|
||||||
|
memcpy(*elements + i * *mybytelen, *pelements + i * *mybytelen, *mybytelen);
|
||||||
|
}
|
||||||
|
sock.Send(*elements, myneles * *mybytelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//memset(*elements, 0x00, *mybytelen);
|
||||||
|
//memset(*pelements, 0x00, *mybytelen);
|
||||||
|
|
||||||
|
return pneles;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t read_psi_test_options(int32_t* argcp, char*** argvp, role_type* role, uint32_t* nruns) {
|
||||||
|
uint32_t int_role;
|
||||||
|
parsing_ctx options[] = {{(void*) &int_role, T_NUM, 'r', "Role: 0/1", true, false},
|
||||||
|
{(void*) nruns, T_NUM, 't', "#of test iterations", false, false},
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!parse_options(argcp, argvp, options, sizeof(options)/sizeof(parsing_ctx))) {
|
||||||
|
print_usage(argvp[0][0], options, sizeof(options)/sizeof(parsing_ctx));
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(int_role < 2);
|
||||||
|
*role = (role_type) int_role;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,28 @@
|
||||||
#ifndef TEST_PSI_H_
|
#ifndef TEST_PSI_H_
|
||||||
#define TEST_PSI_H_
|
#define TEST_PSI_H_
|
||||||
|
|
||||||
|
#define SILENT_TESTS
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include "../pk-based/dh-psi.h"
|
||||||
|
#include "../ot-based/ot-psi.h"
|
||||||
|
#include "../server-aided/sapsi.h"
|
||||||
|
#include "../naive-hashing/naive-psi.h"
|
||||||
|
#include "../util/parse_options.h"
|
||||||
|
#include "../util/helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t test_psi_prot(role_type role, CSocket* sock, uint32_t nelements,
|
||||||
|
uint32_t elebytelen, crypto* crypt);
|
||||||
|
uint32_t plaintext_intersect(uint32_t myneles, uint32_t pneles, uint32_t bytelen, uint8_t* myelements,
|
||||||
|
uint8_t* pelements, uint8_t** result);
|
||||||
|
uint32_t set_up_parameters(role_type role, uint32_t myneles, uint32_t* mybytelen,
|
||||||
|
uint8_t** elements, uint8_t** pelements, CSocket& sock, crypto* crypt);
|
||||||
|
int32_t read_psi_test_options(int32_t* argcp, char*** argvp, role_type* role, uint32_t* nruns);
|
||||||
|
void plot_set(uint8_t* set, uint32_t neles, uint32_t elebytelen);
|
||||||
|
|
||||||
#endif /* TEST_PSI_H_ */
|
#endif /* TEST_PSI_H_ */
|
||||||
|
|
|
@ -52,15 +52,6 @@ uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t* elebyt
|
||||||
intersect_size = otpsi_client(eleptr, neles, nbins, pneles, internal_bitlen, maskbitlen, crypt_env,
|
intersect_size = otpsi_client(eleptr, neles, nbins, pneles, internal_bitlen, maskbitlen, crypt_env,
|
||||||
sock, ntasks, &prf_state, &res_pos);
|
sock, ntasks, &prf_state, &res_pos);
|
||||||
|
|
||||||
//std::sort(res_pos, res_pos+intersect_size);
|
|
||||||
|
|
||||||
//*result = (uint8_t**) malloc(intersect_size * sizeof(uint8_t*));
|
|
||||||
//*res_bytelen = (uint32_t*) malloc(intersect_size * sizeof(uint32_t));
|
|
||||||
/*for(i = 0; i < intersect_size; i++) {
|
|
||||||
(*res_bytelen)[i] = elebytelens[res_pos[i]];
|
|
||||||
(*result)[i] = (uint8_t*) malloc((*res_bytelen)[i]);
|
|
||||||
memcpy((*result)[i], elements[res_pos[i]], (*res_bytelen)[i]);
|
|
||||||
}*/
|
|
||||||
create_result_from_matches_var_bitlen(result, res_bytelen, elebytelens, elements, res_pos, intersect_size);
|
create_result_from_matches_var_bitlen(result, res_bytelen, elebytelens, elements, res_pos, intersect_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +62,12 @@ uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t* elebyt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t elebitlen, uint8_t* elements,
|
uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t elebytelen, uint8_t* elements,
|
||||||
uint8_t** result, crypto* crypt_env, CSocket* sock, uint32_t ntasks, double epsilon,
|
uint8_t** result, crypto* crypt_env, CSocket* sock, uint32_t ntasks, double epsilon,
|
||||||
bool detailed_timings) {
|
bool detailed_timings) {
|
||||||
|
|
||||||
prf_state_ctx prf_state;
|
prf_state_ctx prf_state;
|
||||||
uint32_t maskbytelen, nbins, intersect_size, internal_bitlen, maskbitlen, *res_pos, i, elebytelen;
|
uint32_t maskbytelen, nbins, intersect_size, internal_bitlen, maskbitlen, *res_pos, i, elebitlen;
|
||||||
uint8_t *eleptr;
|
uint8_t *eleptr;
|
||||||
timeval t_start, t_end;
|
timeval t_start, t_end;
|
||||||
|
|
||||||
|
@ -84,16 +75,16 @@ uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t elebitl
|
||||||
|
|
||||||
maskbitlen = pad_to_multiple(crypt_env->get_seclvl().statbits + ceil_log2(neles) + ceil_log2(pneles), 8);
|
maskbitlen = pad_to_multiple(crypt_env->get_seclvl().statbits + ceil_log2(neles) + ceil_log2(pneles), 8);
|
||||||
maskbytelen = ceil_divide(maskbitlen, 8);
|
maskbytelen = ceil_divide(maskbitlen, 8);
|
||||||
elebytelen = ceil_divide(elebitlen, 8);
|
elebitlen = elebytelen * 8;
|
||||||
|
|
||||||
if(elebitlen > maskbitlen) {
|
if(elebitlen > maskbitlen) {
|
||||||
//Hash elements into a smaller domain
|
//Hash elements into a smaller domain
|
||||||
eleptr = (uint8_t*) malloc(maskbytelen * neles);
|
eleptr = (uint8_t*) malloc(maskbytelen * neles);
|
||||||
domain_hashing(neles, elements, ceil_divide(elebitlen, 8), eleptr, maskbytelen, crypt_env);
|
domain_hashing(neles, elements, elebytelen, eleptr, maskbytelen, crypt_env);
|
||||||
internal_bitlen = maskbitlen;
|
internal_bitlen = maskbitlen;
|
||||||
#ifndef BATCH
|
#ifndef BATCH
|
||||||
cout << "Hashing " << neles << " elements with " << elebitlen << " bit-length into " <<
|
cout << "Hashing " << neles << " elements with " << elebitlen << " bit-length into " <<
|
||||||
maskbitlen << " representation " << endl;
|
maskbitlen << " bit representation " << endl;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
eleptr = elements;
|
eleptr = elements;
|
||||||
|
@ -110,10 +101,11 @@ uint32_t otpsi(role_type role, uint32_t neles, uint32_t pneles, uint32_t elebitl
|
||||||
nbins = ceil(epsilon * neles);
|
nbins = ceil(epsilon * neles);
|
||||||
intersect_size = otpsi_client(eleptr, neles, nbins, pneles, internal_bitlen, maskbitlen, crypt_env,
|
intersect_size = otpsi_client(eleptr, neles, nbins, pneles, internal_bitlen, maskbitlen, crypt_env,
|
||||||
sock, ntasks, &prf_state, &res_pos);
|
sock, ntasks, &prf_state, &res_pos);
|
||||||
*result = (uint8_t*) malloc(intersect_size * elebytelen);
|
//*result = (uint8_t*) malloc(intersect_size * elebytelen);
|
||||||
for(i = 0; i < intersect_size; i++) {
|
//for(i = 0; i < intersect_size; i++) {
|
||||||
memcpy((*result) + i * elebytelen, elements + res_pos[i] * elebytelen, elebytelen);
|
// memcpy((*result) + i * elebytelen, elements + res_pos[i] * elebytelen, elebytelen);
|
||||||
}
|
//}
|
||||||
|
create_result_from_matches_fixed_bitlen(result, elebytelen, elements, res_pos, intersect_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(elebitlen > maskbitlen)
|
if(elebitlen > maskbitlen)
|
||||||
|
@ -176,27 +168,23 @@ uint32_t otpsi_client(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_
|
||||||
|
|
||||||
masks = (uint8_t*) malloc(neles * maskbytelen);
|
masks = (uint8_t*) malloc(neles * maskbytelen);
|
||||||
//Perform the OPRG execution
|
//Perform the OPRG execution
|
||||||
|
//cout << "otpsi client running ots" << endl;
|
||||||
oprg_client(hash_table, nbins, neles, nelesinbin, outbitlen, maskbitlen, crypt_env, sock, ntasks, masks);
|
oprg_client(hash_table, nbins, neles, nelesinbin, outbitlen, maskbitlen, crypt_env, sock, ntasks, masks);
|
||||||
|
|
||||||
if(DETAILED_TIMINGS) {
|
if(DETAILED_TIMINGS) {
|
||||||
gettimeofday(&t_start, NULL);
|
gettimeofday(&t_start, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*uint64_t tmpmask = 0;
|
|
||||||
for(uint32_t i = 0; i < neles-1; i++) {
|
|
||||||
memcpy((uint8_t*) &tmpmask, masks + i*maskbytelen, maskbytelen);
|
|
||||||
cout << "Mask " << i << " : " << (hex) << tmpmask << (dec) << endl; //"intersection found at position " << tmpval[0] << " for key " << tmpbuf[0] << endl;
|
|
||||||
}*/
|
|
||||||
#ifdef TIMING
|
#ifdef TIMING
|
||||||
gettimeofday(&t_end, NULL);
|
gettimeofday(&t_end, NULL);
|
||||||
cout << "Client: time for OPRG evaluation: " << getMillies(t_start, t_end) << " ms" << endl;
|
cout << "Client: time for OPRG evaluation: " << getMillies(t_start, t_end) << " ms" << endl;
|
||||||
gettimeofday(&t_start, NULL);
|
gettimeofday(&t_start, NULL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*#ifdef PRINT_BIN_CONTENT
|
#ifdef PRINT_BIN_CONTENT
|
||||||
cout << "Client masks: " << endl;
|
cout << "Client masks: " << endl;
|
||||||
print_bin_content(masks, neles, maskbytelen, NULL, false);
|
print_bin_content(masks, neles, maskbytelen, NULL, false);
|
||||||
#endif*/
|
#endif
|
||||||
//receive server masks
|
//receive server masks
|
||||||
server_masks = (uint8_t*) malloc(NUM_HASH_FUNCTIONS * pneles * maskbytelen);
|
server_masks = (uint8_t*) malloc(NUM_HASH_FUNCTIONS * pneles * maskbytelen);
|
||||||
|
|
||||||
|
@ -265,6 +253,7 @@ uint32_t otpsi_client(uint8_t* elements, uint32_t neles, uint32_t nbins, uint32_
|
||||||
cout << "Time for intersecting:\t\t" << fixed << std::setprecision(2) <<
|
cout << "Time for intersecting:\t\t" << fixed << std::setprecision(2) <<
|
||||||
getMillies(t_start, t_end) << " ms" << endl;
|
getMillies(t_start, t_end) << " ms" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(masks);
|
free(masks);
|
||||||
free(hash_table);
|
free(hash_table);
|
||||||
free(nelesinbin);
|
free(nelesinbin);
|
||||||
|
@ -720,7 +709,7 @@ uint32_t otpsi_find_intersection(uint32_t** result, uint8_t* my_hashes,
|
||||||
} else {
|
} else {
|
||||||
keys_stored = 1;
|
keys_stored = 1;
|
||||||
tmp_hashbytelen = hashbytelen;
|
tmp_hashbytelen = hashbytelen;
|
||||||
tmpkeys = (uint32_t*) malloc(my_neles * keys_stored * sizeof(uint32_t));
|
tmpkeys = (uint32_t*) malloc(my_neles * sizeof(uint32_t));
|
||||||
memcpy(tmpkeys, perm, my_neles * sizeof(uint32_t));
|
memcpy(tmpkeys, perm, my_neles * sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,7 +749,6 @@ uint32_t otpsi_find_intersection(uint32_t** result, uint8_t* my_hashes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: workaround since the masks that are inserted into the hash table are too small and collisions occur
|
|
||||||
if(intersect_ctr > my_neles) {
|
if(intersect_ctr > my_neles) {
|
||||||
cout << "more intersections than elements: " << intersect_ctr << " vs " << my_neles << endl;
|
cout << "more intersections than elements: " << intersect_ctr << " vs " << my_neles << endl;
|
||||||
intersect_ctr = my_neles;
|
intersect_ctr = my_neles;
|
||||||
|
@ -775,8 +763,8 @@ uint32_t otpsi_find_intersection(uint32_t** result, uint8_t* my_hashes,
|
||||||
//cout << "I found " << size_intersect << " intersecting elements" << endl;
|
//cout << "I found " << size_intersect << " intersecting elements" << endl;
|
||||||
|
|
||||||
free(matches);
|
free(matches);
|
||||||
free(map);
|
|
||||||
free(invperm);
|
free(invperm);
|
||||||
|
free(tmpkeys);
|
||||||
return size_intersect;
|
return size_intersect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,8 @@ static void create_result_from_matches_var_bitlen(uint8_t*** result, uint32_t**
|
||||||
*result = (uint8_t**) malloc(sizeof(uint8_t*) * intersect_size);
|
*result = (uint8_t**) malloc(sizeof(uint8_t*) * intersect_size);
|
||||||
*resbytelens = (uint32_t*) malloc(sizeof(uint32_t) * intersect_size);
|
*resbytelens = (uint32_t*) malloc(sizeof(uint32_t) * intersect_size);
|
||||||
|
|
||||||
|
std::sort(matches, matches+intersect_size);
|
||||||
|
|
||||||
for(i = 0; i < intersect_size; i++) {
|
for(i = 0; i < intersect_size; i++) {
|
||||||
(*resbytelens)[i] = inbytelens[matches[i]];
|
(*resbytelens)[i] = inbytelens[matches[i]];
|
||||||
(*result)[i] = (uint8_t*) malloc((*resbytelens)[i]);
|
(*result)[i] = (uint8_t*) malloc((*resbytelens)[i]);
|
||||||
|
@ -101,10 +103,12 @@ static void create_result_from_matches_var_bitlen(uint8_t*** result, uint32_t**
|
||||||
static void create_result_from_matches_fixed_bitlen(uint8_t** result, uint32_t inbytelen, uint8_t* inputs, uint32_t* matches,
|
static void create_result_from_matches_fixed_bitlen(uint8_t** result, uint32_t inbytelen, uint8_t* inputs, uint32_t* matches,
|
||||||
uint32_t intersect_size) {
|
uint32_t intersect_size) {
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
*result = (uint8_t*) malloc(sizeof(uint8_t) * intersect_size);
|
*result = (uint8_t*) malloc(inbytelen * intersect_size);
|
||||||
|
|
||||||
|
std::sort(matches, matches+intersect_size);
|
||||||
|
|
||||||
for(i = 0; i < intersect_size; i++) {
|
for(i = 0; i < intersect_size; i++) {
|
||||||
memcpy(result + i * inbytelen, inputs + matches[i] * inbytelen, inbytelen);
|
memcpy(*(result) + i * inbytelen, inputs + matches[i] * inbytelen, inbytelen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +272,8 @@ static uint32_t find_intersection(uint8_t* hashes, uint32_t neles, uint8_t* phas
|
||||||
uint32_t hashbytelen, uint32_t* perm, uint32_t* matches) {
|
uint32_t hashbytelen, uint32_t* perm, uint32_t* matches) {
|
||||||
|
|
||||||
uint32_t* invperm = (uint32_t*) malloc(sizeof(uint32_t) * neles);
|
uint32_t* invperm = (uint32_t*) malloc(sizeof(uint32_t) * neles);
|
||||||
uint64_t* tmpval;
|
uint64_t *tmpval, tmpkey = 0;
|
||||||
|
uint32_t mapbytelen = min((uint32_t) hashbytelen, (uint32_t) sizeof(uint64_t));
|
||||||
uint32_t size_intersect, i, intersect_ctr;
|
uint32_t size_intersect, i, intersect_ctr;
|
||||||
|
|
||||||
for(i = 0; i < neles; i++) {
|
for(i = 0; i < neles; i++) {
|
||||||
|
@ -278,13 +282,13 @@ static uint32_t find_intersection(uint8_t* hashes, uint32_t neles, uint8_t* phas
|
||||||
|
|
||||||
GHashTable *map= g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL, NULL);
|
GHashTable *map= g_hash_table_new_full(g_int64_hash, g_int64_equal, NULL, NULL);
|
||||||
for(i = 0; i < neles; i++) {
|
for(i = 0; i < neles; i++) {
|
||||||
g_hash_table_insert(map,(void*) ((uint64_t*) &(hashes[i*hashbytelen])), &(invperm[i]));
|
memcpy(&tmpkey, hashes + i*hashbytelen, mapbytelen);
|
||||||
|
g_hash_table_insert(map,(void*) &tmpkey, &(invperm[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0, intersect_ctr = 0; i < pneles; i++) {
|
for(i = 0, intersect_ctr = 0; i < pneles; i++) {
|
||||||
|
memcpy(&tmpkey, phashes+ i*hashbytelen, mapbytelen);
|
||||||
if(g_hash_table_lookup_extended(map, (void*) ((uint64_t*) &(phashes[i*hashbytelen])),
|
if(g_hash_table_lookup_extended(map, (void*) &tmpkey, NULL, (void**) &tmpval)) {
|
||||||
NULL, (void**) &tmpval)) {
|
|
||||||
matches[intersect_ctr] = tmpval[0];
|
matches[intersect_ctr] = tmpval[0];
|
||||||
intersect_ctr++;
|
intersect_ctr++;
|
||||||
assert(intersect_ctr <= min(neles, pneles));
|
assert(intersect_ctr <= min(neles, pneles));
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#define TYPEDEFS_H_
|
#define TYPEDEFS_H_
|
||||||
|
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
//#define BATCH
|
#define BATCH
|
||||||
//#define TIMING
|
//#define TIMING
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user