Download presentation
1
Onion ORAM: A Constant Bandwidth Blowup ORAM
Hi, my name is Chris Fletcher and I will be giving this talk on Onion ORAM. This is joint work between myself, Ling Ren, Srini Devadas, Marten van Dijk, Elaine Shi and Daniel Wichs. Chris Fletcher Joint work with: Ling Ren, Srini Devadas, Marten van Dijk, Elaine Shi, Daniel Wichs
2
Oblivious RAM (ORAM) Server/Adversary Client
Client wishes to ‘securely’ outsource a RAM M The ORAM (on server) encodes M Request(Read, a): returns M[a] Request(Write, a, d’): set M[a] = d’ Client Storage “the ORAM” To start, I will give definitions for ORAM. In this setting, the client wishes to securely outsource a RAM 'M' to a server (which is the adversary). The 'ORAM' itself is a data structure on the server side that encodes M. The client can access the ORAM or RAM with the two natural operations: read and write. Read gets the data at an address 'a' in the RAM. Write updates the data at an address.
3
Oblivious RAM (ORAM) Server/Adversary Client
For client request sequences T, T’ If |T| = |T’|: adversary can’t distinguish ORAM(T) from ORAM(T’) Client ORAM(T) Storage “the ORAM” T = {Request(Rd, a1), Request(Wr, a2, d’), …} ORAM(T) = {implements T, seen by adversary} To define security we will examine an address trace T - that is, a sequence of client requests. T is only seen by the client. We call T, when run under the ORAM protocol, ORAM(T). ORAM(T) is visible to the adversary. ORAM security is then: given two client traces T and T' of the same length, the adversary cannot distinguish ORAM(T) and ORAM(T'). This hides whether each request is a read or write, and also hides the request data, and address pattern.
4
Server computation ORAM
ORAM Server Comp. ORAM Original ORAM Server computation ORAM [AKST’14] Request(Write, Address a1, Data d1) EFHE(Write, a1, d1) Client Server Client Server ORAM time = 1 FHE circuit poly(|M|) accesses EFHE(Read, a2) Request(Read, a2) Alright, so that is ORAM, but this talk is on server computation ORAM, so let me explain the difference. I will abstractly model normal ORAM as follows: we have a client and server and to complete an ORAM request (a write in this case), the client and server interact in a multi interactive protocol given by these dashed arrows. Each dashed arrow is a disk read or write, sent by the client to be completed by the server. A read proceeds similarly, and this process can continue for any polynomial number of accesses in the RAM size. ============================ Now, a very important point is that since ORAM permits both reads and writes, the ORAM's state on the server evolves over time: crucially, we need the ORAM at the end of time = 1 in order to correctly run the protocol at time = 2. This should be obvious since the client is storing a RAM. Now I will explain server computation ORAM, by giving a generic compiler from original to server computation ORAM from AKST'14. That works makes the following observation: we can implement the dashed client-server interactions in a server-side FHE circuit. This saves a lot of bandwidth, at the cost of server computation. As before, reads and writes look similar. But there is a problem with this approach. As I said before, ORAM state evolves over time. What this means when you run FHE over ORAM is that each request's FHE circuit must have an input which comes from the prior FHE circuit in time! Client Server Client Server ORAM time = 2 FHE circuit Data M[a2] Data M[a2]
5
Can we construct server computation ORAM from standard assumptions?
Prior work Server computation ORAM [AKST’14] poly(|M|) depth need FHE, circular security Server Can we construct server computation ORAM from standard assumptions? FHE circuit poly(|M|) accesses The result of this dependency is a circuit with large polynomial depth, which means we will need bootstrapping, which is not that efficient and requires a circular security assumption. ============================ A second issue (that I didn't mention before) is that to get security vs. a malicious adversary, AKST'14 required overlaying SNARKs over their construction - also not very practical and requiring non-standard assumptions. Therefore, the question we wish to address with this talk is: can we construct server computation ORAM from standard assumptions? Malicious security SNARKs Server FHE circuit
6
This work Same client-server bandwidth as AKST’14
A shallow depth ORAM circuit poly(|M|) depth log(|M|) depth Which HE scheme? One instance: Damgård-Jurik cryptosystem (DCR assumption) Compiler to malicious setting (only requires CRHF) See paper. We address this question with two contributions. First, we construct a new ORAM that has shallow circuit depth - log M instead of poly M. This gives us more options in choosing the underlying homomorphic encryption scheme. In particular, we require the scheme have constant ciphertext blowup, allowing us to use (for example) the Damgard-Jurik cryptosystem (based on composite residuosity). I will describe this version of the scheme in this talk. ============================ Secondly, we describe a new way to achieve malicious security from standard assumptions - but I will defer this to the paper. Lastly, we will accomplish this while preserving the bandwidth gains from the prior work AKST'14. In particular, our scheme achieves constant blowup vs. insecure RAM for certain parameters. Same client-server bandwidth as AKST’14 O(1) blowup vs. insecure* * Certain parameters
7
Semi-honest construction 1 – Request 2 – ‘Eviction’ (key idea)
Ok, so the rest of the talk will be an overview of our semi-honest construction. I will first briefly describe ORAM requests - so that you understand how the scheme works functionally. I will spend the most time on ORAM eviction, which is our contribution.
8
Table: map each block to a path
ORAM Structure Tree based ORAM, stores |M| blocks Invariant: if a block is mapped to a path, it must be on that path Client Server Metadata root Will come for free data log |M| Table: map each block to a path We will base our shallow circuit depth ORAM on the Tree ORAM, a popular type of ORAM in the literature. This ORAM is constructed as follows. As before, we have a client and server. The ORAM on the server is implemented as a balanced binary tree of buckets, where each bucket can contain some blocks (I have highlighted one block in red). Each block is stored alongside some metadata - which is encrypted along with the block. This metadata tracks block ID along with some other helper information I will overview shortly. ============================ Now, the most important invariant in the scheme is that at every point, each block is mapped to a uniform random path in the tree, which means the block must live somewhere on that path. Here, a path traverses from the root to some tree leaf. The client tracks this map in the green structure to the left. For example, if the red block is mapped to path 1, it may live anywhere on the blue path. We will track this information in the block metadata as well. A parting note. I will assume the green map can be implemented as a black box oracle for the rest of the talk. This is because, asymptotically, it will come for free in all of our parameterizations. (red block, path 1) Must be on blue path Path
9
Just like other Tree ORAMs Append to root Eventual Overflow
ORAM Request Lookup map, find path 1 Download blocks & metadata on path “Remove” red block, remap to new path Append red block to root Client Read red block Server root Just like other Tree ORAMs Map: blocks path Append to root Eventual Overflow (very important!) (red block, path 1) (red block, path 3) Alright, that was the ORAM's structure, now I will describe the request operation. Disclaimer: this is exactly like other tree ORAMs; I am going over it to setup the eviction operation. Ok, say we wish to access the red block. In the first step the client looks up the map and finds that the red block is mapped to path 1. Second, the client downloads the metadata and blocks on the path. By decrypting the metadata, the client finds the red block and logically removes it from the server by updating and writing back the metadata. ============================ The client performs a very important operation: it remaps the block to a new random leaf. THIS is the crucial step for security. It ensures that repeated requests to this block will go down different paths each time. Finally, the client updates the red block and appends it to the server's root bucket to complete the access. This is also very important: each access REMOVES a block from the tree and appends it back to the root. Eventually, the root will overflow and this is why we need an eviction routine. Leaf
10
ORAM Request, w/ HE PIR Client Server Read red block Map:
Replace downloads with PIR Same as prior work AKST’14 Client Read red block Server PIR Map: blocks path (red block, path 1) Ok, very quickly I will mention how combine the request operation with homomorphic encryption. Basically what you do is replace the path download with a PIR over the path - which saves bandwidth. THATS IT. Other steps, including appending the block back to the root remain the same. That is all I have time to say about it. Path 1
11
Semi-honest construction 1 – Request 2 – Eviction (key idea)
Ok! We are done with requests and are now at the important part: ORAM eviction.
12
Layered HE Select Operation
Sequence of J Damgård-Jurik instances For i = [1…J]: Plaintext space i Ciphertext space i = Plaintext space i+1 Onion encrypt to move from i i + 1 Select( Ei+1(index k), Ei(Blocks[1…n]) ) Ei+1( Blocks[k] ) Select Inputs i layers Output i+1 layer Client Client determines k through block metadata. Now, we need some preliminaries on the Damgard-Jurik homomorphic encryption scheme. For our ORAM, we will require multiple instances of Damgard-Jurik (call this J) and we will set these instances up so that for each instance i < J, the ciphertext space of instance i is equal to the plaintext space of instance i+1. With this setup, you move between instances by repeatedly encrypting (onion encrypting) the ciphertext. ============================ Ok, with this setup, Damgard-Jurik gives us the following Select primitive. At a high level, it takes an encrypted index, an array of encrypted blocks and outputs an encryption of the selected block. This is highly remeniscant of PIR: the client will provide the index and the server will supply the blocks. I will note that the client will calculate k by downloading block metadata like you saw in the request operation. In our select operation, however, we will tolerate the input blocks to be onion encrypted using Damgard-Jurik some number i times. What our select operation gives us is a way to select a block that has been onion encrypted, and outputs the desired block under an additional layer of onion encryption. To repeat: inputs have i layers and outputs have i+1 layers. This onioning is central to the scheme and is where Onion ORAM gets its name! Server
13
Idea Behind Eviction Push blocks in root to tree leaves. HE Select
Block A, Path 1 After some requests … HE Select + Encryption layers Merge w/ Other blocks HE Select Ok, now we are ready to talk about eviction. In a nutshell, eviction pushes blocks, that have accumulated in the tree root, down to the tree leaves so that no bucket overflows. Our goal will be to perform this operation locally at the server. For example, say some blocks have accumulated at the root. We will use the homomorphic select operation to push those blocks to a lower bucket. There are typically blocks already there so we have to perform a merge, and each time we do it adds encryption layers. ============================ Then we basically continue this on a schedule all the way down. The big question is: how many layers accumulate? + Encryption layers Merge w/ Other blocks 1 2 3 4
14
Problem Blocks can get stuck in buckets. A1 B1 C2 C5 C4 C3
A1 = Block A with 1 layer C2 C5 C4 C3 Select(𝑖𝑛𝑑𝑒𝑥 𝐶, B1, A1, C3) Select(𝑖𝑛𝑑𝑒𝑥 𝐶, B1, A1, C4) Select(𝑖𝑛𝑑𝑒𝑥 𝐶, B1, A1, C2) Select(𝑖𝑛𝑑𝑒𝑥 𝐶, B1, A1, C1) The answer is a lot. The issue is in all prior tree ORAMs, blocks get stuck in buckets for indeterminate amounts of time. This may be due to congestion down the tree. For example say I want to move blocks A and B down the tree (syntax A sub 1 means block A has one onion layer so far). If C can get stuck, my select operation to C's slot must include C as an input - so it doesn't get overwritten. That means the output of the select is C with 2 layers. The next time, it's C with 3 layers, etc. In general, after poly M evictions we get poly M layers and the scheme fails due to too much ciphertext blowup. ============================ This is the same as having poly M circuit depth. The rest of the talk is about how to break this feedback loop. Next slides O(poly |M|) evictions Slot C gets O(poly |M|) layers O(poly |M|) Circuit depth
15
Solution Design our ORAM eviction such that
buckets are guaranteed to be empty regularly A1 B1 Select(𝑖𝑛𝑑𝑒𝑥 𝐴, B1, A1) In a nutshell, our solution to break the loop is to design a new ORAM eviction so that buckets are guaranteed to be empty regularly. With this, the select operation between A and B will write into an empty slot and the feedback is broken.
16
ORAM Eviction, w/o HE Empty!
Design our ORAM eviction such that buckets are guaranteed to be empty regularly Evict down path, 1 bucket triplet at a time For each triplet: push all blocks to children Set params s.t. Pr[child overflows] = negl(security param) Several more things … Empty! What does this eviction look like? First, when we evict we will do so down a path of the tree, and consider one bucket triplet at a time. For example, if we evict to path 6 we evict down the grey path and partition the path into these triplets. Second, for each triplet (top to bottom) we will push all blocks in the parent bucket to its two children, like this. Third, we will set parameters so that the probability that a child overflows is negligible in a security parameter. ============================ With these three steps, we have a very nice property: namely, the parent bucket in each triplet is guaranteed to be empty after each eviction. Lastly, its not obvious but for this all to work we need to evict over a special ordering of paths - I won't explain it suffice to say it is necessary. Example: evict to path 6
17
Encryption layer bound = Buckets at level i get ≤ i layers
ORAM Eviction w/ HE Encryption layer bound = O(ORAM tree height) = O(log |M|) Block A, Path 1 Level i-1 HE Select Sometimes destination = empty Level i NO Additional Encryption layers Alright, we are basically done. Putting it all together, when we perform select operations on eviction, we will sometimes have that the destination bucket is empty, which means we don't need to add layers on a select. This is sufficient to prove that all buckets at level i never accrue more than i layers, which is sufficient to get a log M circuit depth and a performant scheme. Buckets at level i get ≤ i layers
18
Summary O(1) bandwidth blowup ORAM
w/ standard assumptions & cheaper crypto (Another) step towards ORAM in practice [See MMB’15 for better parameters] More stuff in paper Compiler for malicious security Construction using BGV SWHE Asymptotic & concrete evaluation Optimizations, proofs, etc
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.