Refence: Oblivious Data Structures*(Xiao Shaun Wang1, Kartik Nayak1, Chang Liu1, T-H. Hubert Chan2,
Elaine Shi1, Emil Stefanov3, and Yan Huang4)
Oblivious Data Structure在渐进性和实践中比著名的O-RAM方案好。
对于一些对访问模式有预见性的算法,有自定义的、渐进的、更有效的结构是有利的。算法的访问模式图有存储单元作为节点,并且只有当相应节点之间存在有向边时,两个单元才能被连续访问。因此,对于一般的RAM程序,它们的访问模式可以是一个完整的图。通用数据结构具有更稀疏的访问模式图,与对数据进行任意随机访问的通用RAM程序相比。例如,对于二叉搜索树或堆,内存访问只能从一个树节点到相邻的节点,因此通过不隐藏访问模式的一些公开的方面,我们应该能够获得一些效率(与ORAM相比)。对于稀疏访问图的两种不同的刻画,与一般ORAM方案相比,Oblivious Data Structure获得了渐近性能增益。
Applications
稀松访问模式图的这两种描述为常见的工作引起了众多的应用:
Techniques
以下两个主要的技术来构造稀疏访问模式图的茫然数据结构。
数据结构D是一个支持特定类型操作(insert,del,or lookup)的数据集合。每个操作都由一些操作数参数化(例如,要查找的键)。ODS的目标是确保任意两个包含k个操作的序列,他们的访问模式必须是不可区分的。这意味着访问模式(包括访问次数)不应该泄露操作码(操作类型)和操作数(key和data)的信息。
Definition 1(Oblivious data structure)我们认为数据结构D是茫然的,设存在一个多项式时间模拟器S,这样对于任意多项式长度序列的数据结构操作 o p s ⃗ \vec{ops} ops =( (op1,arg1),(op2,arg2),…,(opM,argM) )
addressesD( o p s ⃗ \vec{ops} ops)== S(L( o p s ⃗ \vec{ops} ops ))
其中addressesD( o p s ⃗ \vec{ops} ops)是由茫然数据结构在一系列操作 o p s ⃗ \vec{ops} ops期间产生的物理地址;并且L( o p s ⃗ \vec{ops} ops )称为泄露函数。通常我们认为L( o p s ⃗ \vec{ops} ops ) = M,即操作数的数量被泄露了,但没有其他的。
直观地说,这个定义表示由一系列数据结构操作产生的访问模式应该只显示操作的总数。也就是说,多项式时间模拟器S只知道操作的总次数,就可以模拟物理地址,这样多项式时间的识别器就无法区分被遗忘的数据结构生成的模拟地址和真实地址。
请注意,直接使用标准ORAM可能不能满足我们的定义,因为信息可能会通过访问的数量泄露。具体来说,某些数据结构操作比其他操作需要更多的内存访问;例如,AVL树的删除可能会引起旋转操作,因此会比查找操作引起更多的内存访问。因此,即使我们使用标准的ORAM,也可能需要填充来隐藏正在执行的数据结构操作。
Figure1:静态茫然二叉查找树. 左边二逻辑二叉查找树,右边是如何将这些节点非递归的存储在基于位置的ORAM上。每个位置标记指定到树中叶结点的路径。每个父类都指向其子类的位置标签,这样我们就可以省去查找position map的需要,从而与通用ORAM相比节省了O(log N)因子。
Node format. 在ODS这个数据结构中,每个节点都由标识符id和它的位置标签pos来标识,节点还存储了它所有子节点的位置标签。因此,每个节点的格式为node := (data,id,pos,childrenPos) ,特别地,childrenPos是从每个子id映射到它的位置标记。记为childrenPos[idc] 表示以idc标识的子类的位置标签。
所有节点将被(加密并)存储在服务器上基于位置的ORAM(非递归)中。客户端只存储树根的位置标记和标识符。
注意一旦一个节点被服务器获取,他的位置标记就会暴露给服务器,因此我们需要为这个节点生成一个新的位置标记。同时,这个位置标记也应该在他父节点的子类位置列表中更新。我们的关键思想是依赖O(logN)大小的客户端缓存,这样在整个插入操作中,与此操作有关的所有节点都被获取一次。在这些阶段被从服务器获取和删除后,他们将被储存在客户端缓存中。这样客户端可以在写回他们之前在本地对这些节点进行更新。这些更新可能包括插入、删除、和修改图结构(如AVL树示例中的旋转)。最后,在操作结束时,本地缓存的所有节点将被写回服务器。在回写之前,所有被获取的节点必须被随机分配新的位置标签,他们的父节点必须被适当的修改,以指向子节点的新位置标签。
内存为存储上述数据结构图中的节点提供了空间。该图中的每个节点(id, data)都是一个原子存储单元,其中id可以视为节点在内存中的地址。我们定义了以下四种类型的内存操作:
Read(id), Write(id,data*), Insert(id,data*), Del(id)
任何的数据结构算法可以用这四个类型的内存操作以及内存操作之间的计算步骤(例如,键值的比较)来表示。
请注意,相比之下,标准的通用的ORAM通常只支持read(id)和write(id,data* )操作,但不支持insert(id,data* )和del(id)。附加的insert(id,data*)和del(id)操作是为了方便表示动态数据结构操作,如插入和删除。
ODS 客户端. 在普通的、非茫然的数据结构中,内存操作直接进入内存,从而通过访问模式泄露信息。在茫然数据结构中,我们将使用一个专门设计的“茫然内存”替换内存,称为ODS客户端。这个ODS客户端的角色类似于ORAM客户端;从数据结构程序的角度来看,它提供了与内存完全相同的接口(即支持前面提到的四种操作)。在内部,ODS客户机将逻辑内存请求转换为一系列混淆的内存访问,并将混淆的物理地址显示给不受信任的服务器。
显然,一种简单但低效的方法是简单地使用通用ORAM客户机作为ODS客户机。但是,我们将构造一个定制的ODS客户机,它将带来渐近的加速。
**不受信任的服务器.**不受信任的服务器支持getphys addr和putphys addr, data的简单接口。服务器不应该从被访问的物理地址序列中获得任何信息。
每个(动态)数据结构操作实现如下: