Oblivious RAM for Scala
This is a library designed to provide an Oblivious RAM
and some higher-level tools on top of it.
More specifically, Lethe is an implementation of Path ORAM.
It is a model that helps when designing applications that delegate an untrusted
server with access to their data (think cloud computing). Of course, in such a
situation, one should encrypt the data on the client side.
Turns out this
is not enough. Observation of the access
patterns to the data can allow an attacker to gain significant information. As
shown in the papers above, actual attacks can be mounted and this is not only a
theoretical concern.
Oblivious RAM models a random access data structure giving guarantees that the
attacker will not learn anything other than the frequency of access and the
overall size of data. Various techniques exist, all based on the idea of
continuously shuffling memory as it is being accessed.
Lethe is an implementation of Path ORAM.
The end goal is to provide a complete implementation of Path ORAM in Scala, that
works both on the JVM and in Scala.js.
On top of that, various higher-level features can be constructed:
Eventually, the long term aim would be to provide a deployable server together
with a client library of data structures that can be mapped on the server and
some form of SQL support.
Currently Lethe contains a basic implementation of Path ORAM that uses
ZeroMQ to communicate synchronously with a server.
The server is very minimal, and can either work in memory, or use
LevelDB as a storage backend to
persist data across sessions.
A recursive form of the Path ORAM algorithm is used to minimize the amount of
data that the client has to keep.
On top of that, a very basic form of indexing is developed, allowing search
on both structured data and free text.
A lot remains to be done, and here is a tentative plan:
A Remote
is an interface to read and write blocks of data, possibly to a
server. A trivial example is MemoryRemote
, that just keeps the blocks in
memory without sending them at all. Alternatively, ZMQRemote
talks to an
actual remote ZeroMQ server.
A Serializer[A]
is used to convert between and Array[Byte]
and back;
by default we use BooPickle to handle this.
A Crypter
handles encryptions and decryption, working at the byte array
level. An example is the AESCrypter
.
A Client[A]
has access to all of them, and used this to talk to the server,
sending and receiving encrypted instances of A
. In particular,StandardClient[A]
just puts together the three.
An ORAM
has access to a Client
that communicates to a server
and makes sure that one can read or write instances of Doc
, indexed by Id
.
The TrivialORAM
does this by always reading and writing back all
documents for all operations.
PathORAM
does this by implementing the actual Path ORAM construction.
The index that maps each Id
to the relative Path
is kept abstract in
order to handle recursion. In LocalPathORAM
, we specialize the index
to be a local Map[Id, Path]
, while RecursivePathORAM
stores the
index as an ORAM itself.