#include #include #include #include #include #include #include #include using std::map; #include "pirserver.h" // This is a toy "private" (not really private) lookup protocol. // It is only here to show you how to implement a subclass of PIRServer. // Do not use this code for anything requiring actual privacy. // // The params are a random 32-byte string. Lookups are done by // "encrypting" the lookup key by XORing it with the param string. // The reply is XORed with repeated copies of the same string. class ToyServer : public PIRServer { private: string xorkey; map table; public: ToyServer(); // Fill the current params into the passed string argument virtual void get_params(string ¶ms); // Store the given value at the given key. If the value is the // empty string, delete the key. If the key has already been // stored, overwrite the value with this one. The key will be // exactly 32 bytes long. virtual void store(const string &key, const string &value); // Perform a private lookup. The client's private query message is // lookup_query. If successful, return true and fill // lookup_response with the private response. If unsuccessful, // return false. virtual bool lookup(const string &lookup_query, string &lookup_response); }; ToyServer::ToyServer() { // Initalize xorkey with a 32-byte random string char randstr[32]; int rfd = open("/dev/urandom", O_RDONLY); if (rfd < 0 || read(rfd, randstr, 32) < 32) { // Can't even read random data? perror("reading random string"); exit(1); } close(rfd); xorkey.assign(randstr, 32); } void ToyServer::get_params(string ¶ms) { params.assign(xorkey); } void ToyServer::store(const string &key, const string &value) { if (value.length() > 0) { table[key] = value; } else { table.erase(key); } std::cerr << "stored (" << key.length() << ") " << key << "\n"; } bool ToyServer::lookup(const string &lookup_query, string &lookup_response) { if (lookup_query.length() != 32) { return false; } // Decrypt the query string plain_query(lookup_query); for (size_t i=0;i<32;++i) { plain_query[i] ^= xorkey[i]; } // Do the lookup map::const_iterator iter = table.find(plain_query); if (iter != table.end()) { lookup_response.assign(iter->second); // Encrypt the result size_t response_size = lookup_response.length(); for (size_t i=0;i