Jump to content

Oblivious RAM

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Nithvarma (talk | contribs) at 04:00, 9 May 2016 (→‎Definition). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

An Oblivious RAM (ORAM) simulator is a compiler that transforms algorithms in such a way that the resulting algorithms preserve the input-output behavior of the original algorithm but the distribution of memory access pattern of the transformed algorithm is independent of the memory access pattern of the original algorithm. The definition of ORAMs is motivated by the fact that an adversary can obtain nontrivial information about the execution of a program and the nature of the data that it is dealing with, just by observing the pattern in which various locations of memory are accessed during its execution. An adversary can get this information even if the data values are all encrypted. The definition suits equally well to the settings of protected programs running on unprotected shared memory as well as a client running a program on its system by accessing previously stored data on a remote server. The concept was formulated by Oded Goldreich in 1987.[1]


Definition

A Turing machine (TM), the mathematical abstraction of a real computer (program), is said to be oblivious if for any two inputs of the same length, the motions of the tape heads remain the same. Pippenger and Fischer[2] proved that every TM with running time can be made oblivious and that the running time of the oblivious TM is . A more realistic model of computation is the RAM model. In the RAM model of computation, there is a CPU that can execute the basic mathematical, logical and control instructions. The CPU is also associated with a few registers and a physical random access memory, where it stores the operands of its instructions. The CPU in addition has instructions to read the contents of a memory cell and write a specific value to a memory cell. The definition of ORAMs capture a similar notion of obliviousness memory accesses in this model.

Informally, an ORAM is an algorithm at the interface of a protected CPU and the physical RAM such that it acts like a RAM to the CPU by querying the physical RAM for the CPU while hiding information about the actual memory access pattern of the CPU from the physical RAM. In other words, the distribution of memory accesses of two programs that make the same number of memory accesses to the RAM are indistinguishable from each other. This description will still make sense if the CPU is replaced by a client with a small storage and the physical RAM is replaced with a remote server with a large storage capacity, where the data of the client resides. It is an extension of the notion of Oblivious Turing machines to the RAM model of computation.

The following is a formal definition of ORAMs.[3] Let denote a program requiring a memory of size when executing on an input . Suppose that has instructions for basic mathematical and control operations in addition to two special instructions and , where reads the value at location and writes the value to . The sequence of memory cell accessed by a program during its execution is called its memory access pattern and is denoted by .

A polynomial-time algorithm, is an Oblivious RAM (ORAM) compiler with computational overhead and memory overhead , if given and a deterministic RAM program with memory-size outputs a program with memory-size such that for any input , the running-time of is bounded by where is the running-time of , and there exists a negligible function such that the following properties hold:

  • Correctness: For any and any string , with probability at least , .
  • Obliviousness: For any two programs , any and any two inputs, if , then is -close to in statistical distance, where and .

Note that the above definition uses the notion of statistical security. One can also have a similar definition for the notion of computational security.

History of ORAMs

ORAMs were introduced by Goldreich et al.[1][4][5] where in the key motivation was stated as software protection from an adversary who can observe the memory access pattern (but not the contents of the memory).

The main result in this work[5] is that there exists an ORAM compiler that uses server space and incurs a running time overhead of when making a program that uses memory cells oblivious. This work initiated a series of works in the construction of oblivious RAMs that is going on till date. There are several attributes that need to be considered when we compare various ORAM constructions. The most important parameters of an ORAM construction are the amounts of client storage, the amount of server storage and the time overhead in making one memory access. Based on these attributes, the construction of Kushilevitz et al.[6] is the best known ORAM construction. It achieves client storage, server storage and access overhead.

Another important attribute of an ORAM construction is whether the access overhead is amortized or worst-case. Several of the earlier ORAM constructions have good amortized access overhead guarantees, but have worst-case access overheads. Some of the ORAM constructions with polylogarithmic worst-case computational overheads are.[6][7][8][9][10] The constructions of[1][4][5] were for the random oracle model, where the client assumes access to an oracle that behaves like a random function and returns consistent answers for repeated queries. They also noted that this oracle could be replaced by a pseudorandom function whose seed is a secret key stored by the client, if one assumes the existence of one-way functions. The papers[11][12] were aimed at removing this assumption completely. The authors of[12] also achieve an access overhead of , which is just a log-factor away from the best known ORAM access overhead.

While most of the earlier works focus on proving security computationally, there are more recent works[3][8][11][12] that use the stronger statistical notion of security.

One of the only known lower bounds on the access overhead of ORAMs is due to Goldreich et al.[5] They show a lower bound for ORAM access overhead, where is the data size. There is also a conditional lower bound on the access overhead of ORAMs due to Boyle et al.[13] that relates this quantity with that of the size of sorting networks.

A simple ORAM scheme

A statistically secure ORAM compiler constructed by Chung and Pass[3] will be described in the following with the proof of its correctness. The compiler on input and a program with its memory requirement , outputs an equivalent oblivious program .

If the input program uses registers, the output program will need registers, where is a parameter of the construction. uses memory and its (worst-case) access overhead is .

The ORAM compiler is very simple to describe. Suppose that the original program has instructions for basic mathematical and control operations in addition to two special instructions and , where reads the value at location and writes the value to . The ORAM compiler, when constructing , simply replaces each and instructions with subroutines and and keeps the rest of the program the same. It may be noted that this construction can be made to work even for memory requests coming in an online fashion.

The ORAM compiler substitutes the read and write instructions in the original program with subroutines Oread and Owrite.

Memory organization of the oblivious program

The program stores a complete binary tree of depth in its memory. Each node in is represented by a binary string of length at most . The root is the empty string, denoted by . The left and right children of a node represented by the string are and respectively. The program thinks of the memory of as being partitioned into blocks, where each block is a contiguous sequence of memory cells of size . Thus, there are at most blocks in total. In other words, the memory cell corresponds to block .

At any point of time, there is an association between the blocks and the leaves in . To keep track of this association, also stores a data structure called position map, denoted by , using registers. This data structure, for each block , stores the leaf of associated with in .

Each node in contains an array with at most triples. Each triple is of the form , where is a block identifier and is the contents of the block. Here, is a security parameter and is .

Description of the oblivious program

The program starts by initializing its memory as well as registers to . Describing the procedures and is enough to complete the description of . The procedure is given in Algorithm~\ref{Owrite}. The inputs to the procedure are a memory location and the value to be stored at the location .

Here, we give a high level overview of the sub-routine. The task of the phase is to look for the location in the tree . Suppose pos is the leaf associated with the block containing location . For each node in on the path from root to , this procedure goes over all triples in and looks for the triple corresponding to the block containing . If it finds that triple in , it removes the triple from and writes back the updated state of . Otherwise, it simply writes back the whole node . In the next phase, it updates the block containing with the new value , associates that block with a freshly sampled uniformly random leaf of the tree, writes back the updated triple to the root of . The last phase, which is called , is an additional operation to release the memory cells in the root and other higher internal nodes. Specifically, the algorithm chooses a uniformly random leaf and then tries to push down every node as much as possible along the path from root to . It aborts outputting an overflow if at any point some bucket is about to overflow its capacity.

The procedure is similar to and we do not give a full pseudo-code for that. For the procedure, the input is just a memory location and it is almost the same as . In the stage, if it does not find a triple corresponding to the location , it returns as the value at location . In the phase, it will write back the same block that it read to the root, after associating it with a freshly sampled uniformly random leaf.

Oblivious simulation

Now that we have define both and , it is left only specify what is meant by an of an arbitrary program on an , our notion of simulation is minimal one: it only requires that both machines compute the same function. The simulation presented in the sequel are simulations in a much stronger sense: specifically, they are “on-line”. On the other hand, an oblivious simulation of a is not merely a simulation by an oblivious RAM. In addition, we require that inputs having identical running-time on the original , maintain identical running-time on the Oblivious , so that the obliviously condition applies to them in a non-vacuous manner. For the sake of simplicity, we present only definition for oblivious simulation of deterministic RAMs.

Definition of of : Given , and , we say that a , obliviously simulates if the following conditions hold.

1. The simulates with probability 1. In other words, for every input y, and every choice of an oracle function , the output of , on input and access to oracle , equals the output of on input .

2. The is oblivious. (We stress that we refer here to the access pattern of on a fixed input and a randomly chosen oracle function.)

3. The random variable representing the running-time of is fully specifies by the running-time (on input ).(Here again we refer to the behavior of on fixed input and a randomly chosen oracle function.)

Hence, the access pattern in an oblivious simulation (which is a random variable defined over the choice of the random oracle) has a distribution depending only on the running-time of the original machine. Namely, let denote the access pattern in an oblivious simulation of the computation of on input . Then, and are identically distributed if the running-time of on these inputs (i,e., and ) is identical.

We note that in order to define oblivious simulations of , we have to supply the simulating with two oracles (i.e., one identical to the oracle of the simulated machine and the other being a random oracle). Besides, these two oracles can be incorporated into one, but in any case the formulation will be slightly more cumbersome.

We need to define the overhead of oblivious simulation.

Definition of Overhead of Oblivious Simulations:

Given , , and suppose that a , obliviously simulates the computation of , and let y: be a function. We say that the overhead of the simulation is at most if, for every , the expected running-time of on input is bounded above by , where denoted the running-time of on input .

Solution

Computer model construction

  • Two parts: Memory and Processors
  • Internal memory of process:
  • Interaction: ,
  • Processor has access to random oracle
  • Computation starts with a program and an input in
  • One step: fetch one cell - update value and Processor memory - store

Oblivious execution

We want to hide orders of access to cells of , thus we define Oblivious Execution as for all programs of size working in time , an order of fetch/store address is the same. The weaker requirement is for all programs of size working in time , order of fetch/store address has the same distribution.

Basic solution

Naive simulation

  1. We store encrypted pairs(address, value) in memory cells
  2. For every fetch/store we scan through all memory. If the address is wrong, re-encrypt and store the data, otherwise, do the job which means encrypt and store the results.

Cost of simulation: time, memory

Square root solution

We need to protect order of accesses and number of accesses. Because , the idea comes that: firstly we divide computation in epochs of steps each. Then on each original step, we make one fetch to the and scan through all the .

Square Root simulation

  1. Store input in the
  2. Add dummy cells to the
  3. for every epoch of steps
    1. Permute all cells in the (using permutation from random oracle)
    2. For each process() scan through the . If element is not founded, fetch it from , otherwise fetch next dummy cell
    3. Update(Obliviously) the using the values

Cost of simulation: time, memory

Buffer solution

Buffer solution refers to Oblivious Hash Table. Suppose we have a memory of initial program:

  1. Take a hash function h :
  2. Prepare table
  3. Put to a random free call in column
  4. The chance of overflow is less than

Simulation:

  1. Construct (obliviously) a hash table
  2. For every step of initial program
    1. Scan through column
    2. Update the target cell

Cost of simulation : time, memory

Hierarchical construction

Data structure : Oblivious Data Structure

  • = table
  • Hierarchical Buffer Structure =
  • Initial position : input in last buffer, all others are empty

Hierarchical simulation

Simulation of processing cell :

  1. Scan through
  2. For every j scan through -th column in
  3. Put the updated value to the first buffer

Periodic rehashing

Refreshing the data structure:

  1. Every steps unify -th and -th buffer
  2. Delete doubles
  3. Using new hash function put all data to level

Invariant: For every moment of time for every buffers from 1 to all together contain at most elements.

Cost of simulation: time, memory

Omitted details: realization of oblivious hashing and random oracle

Trivial solution

The trivial solution is, for every read or write operation, read from and write to every single element in the array, only performing a meaningful action for the address specifies in the single operation.

The trivial solution of Oblivious Algorithm(S) will scan through the entire array for each operation and then consult every element in RAM. For sequence S, such that |S| = m, perform on an array of size n, the running time complexity of the Oblivious-Algorithm(S) is Ω(m*n). Therefore, when n is incredibly large, this algorithm is actually inefficient.

Sorting network

When allowing for parallel comparators, we can trivially sort an array in O(n) time. But there are much better sorting networks. Optimally, there is a way to getting O(n logn) comparisons in O(logn) parallel time.[14]

References

  1. ^ a b c Oded Goldreich. 1987. Towards a theory of software protection and simulation by oblivious RAMs. In Proceedings of the nineteenth annual ACM symposium on Theory of computing (STOC '87), Alfred V. Aho (Ed.). ACM, New York, NY, USA, 182-194. DOI=http://dx.doi.org/10.1145/28395.28416
  2. ^ Nicholas Pippenger and Michael J. Fischer. 1979. Relations among complexity measures. Journal of ACM. DOI = http://dl.acm.org/citation.cfm?id=322138
  3. ^ a b c Kai-Min Chung and Rafael Pass. 2013. A simple ORAM. IACR Cryptology ePrint Archive. DOI = http://eprint.iacr.org/2013/243
  4. ^ a b Rafail Ostrovsky. Efficient computation on oblivious rams. In Proceedings of the 22nd Annual ACM Symposium on Theory of Computing, May 13–17, 1990.
  5. ^ a b c d Oded Goldreich and Rafail Ostrovsky. Software protection and simulation on oblivious rams. Journal of ACM.1996
  6. ^ a b Eyal Kushilevitz, Steve Lu, and Rafail Ostrovsky. On the (in) security of hash-based oblivious ram and a new balancing scheme. In Proceedings of the twenty-third annual ACM-SIAM symposium on Discrete Algorithms. 2012
  7. ^ Rafail Ostrovsky and Victor Shoup. Private information storage (extended abstract). In Proceedings of the Twenty-Ninth Annual ACM Symposium on the Theory of Computing. 1997.
  8. ^ a b Elaine Shi, T-H Hubert Chan, Emil Stefanov, and Mingfei Li. Oblivious ram with worst-case cost. In Advances in Cryptology. ASIACRYPT 2011.
  9. ^ Michael T. Goodrich, Michael Mitzenmacher, Olga Ohrimenko, and Roberto Tamassia. Oblivious ram simulation with efficient worst-case access overhead. In Proceedings of the 3rd ACM workshop on Cloud computing security workshop. 2011.
  10. ^ Kai-Min Chung, Zhenming Liu, and Rafael Pass. Statistically-secure ORAM with overhead. In Advances in Cryptology - ASIACRYPT 2014.
  11. ^ a b Miklos Ajtai. Oblivious rams without cryptographic assumptions. In Proceedings of the 42nd ACM Symposium on Theory of Computing, STOC. 2010
  12. ^ a b c Ivan Damgard, Sigurd Meldgaard, and Jesper Buus Nielsen. Perfectly secure oblivious RAM without random oracles. In Theory of Cryptography Conference, TCC. 2011
  13. ^ Elette Boyle and Moni Naor. Is there an oblivious RAM lower bound? In Proceedings of the 2016 ACM Conference on Innovations in Theoretical Computer Science. 2016.
  14. ^ Ajtai, M.; Komlós, J.; Szemerédi, E. (1983). An O(n log n) sorting network. STOC '83. Proceedings of the fifteenth annual ACM symposium on Theory of computing. pp. 1–9. doi:10.1145/800061.808726. ISBN 0-89791-099-0.
  • J. Bentley (2000), Programming Pearls 2nd Edition. Addison-Wesley, Inc. ISBN 0-201-65788-0
  • Eyal Kushilevitz, Steve Lu, and Rafail Ostrovsky. On the (in) security of hash-based oblivious ram and a new balancing scheme. In Proceedings of the twenty-third annual ACM-SIAM symposium on Discrete Algorithms, pages 143–156. SIAM, 2012.
  • Knuth, D. E. (1973). The Art of Computer Programming, volume 3: Sorting and Searching.Addison Wesley.
  • Oded Goldreich, Rafail Ostrovsky. Software protection and simulation on oblivious RAMs. Published in Journal of the ACM (JACM), volume 43 issue 3, May 1996, page 431-473.
  • Yuqun Chen, Ramarathnam Venkatesan, Matthew Cary, Ruoming Pang, Saurabh Sinha, and Mariusz H. Jakubowski. Oblivious hashing: A stealthy software integrity verification primitive. Microsoft research, 2002.

See also