|
@@ -0,0 +1,111 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include <fcntl.h>
|
|
|
+
|
|
|
+#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);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
|
+}
|