Browse Source

A toy private lookup protocol

Ian Goldberg 3 years ago
parent
commit
edfa6932e7
2 changed files with 113 additions and 0 deletions
  1. 2 0
      Makefile
  2. 111 0
      toyserver.cc

+ 2 - 0
Makefile

@@ -1,2 +1,4 @@
 CXXFLAGS=-g -Wall
 
+toyserver: toyserver.o pirserver.o
+	$(CXX) -o $@ $^

+ 111 - 0
toyserver.cc

@@ -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 &params);
+
+    // 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 &params)
+{
+    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;
+}