123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <iostream>
- #include <map>
- 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<string, string> 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<string,string>::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<response_size;++i) {
- lookup_response[i] ^= xorkey[i % 32];
- }
- return true;
- }
- return false;
- }
- int main(int argc, char **argv) {
- ToyServer server;
- server.mainloop();
- return 0;
- }
|