超高效聚合历史无关的持久认证字典
1. 引言
在当今数字化时代,数据的安全存储和验证至关重要。以加密和防篡改的方式存储数据成为了研究热点。早期的Merkle树就是这样一种数据结构,每个节点包含其子节点内容的加密哈希值,根节点的哈希值固定了整棵树的值。基于哈希的数据结构已广泛应用于智能卡、外包数据库、分布式文件系统、图和几何搜索、防篡改日志等众多系统中。
这些系统通常围绕认证字典抽象构建,支持普通字典操作,查找操作会返回答案及其正确性的证明。在数据随时间变化的系统中,如股票行情数据、版本控制系统或公钥基础设施,参与者不仅希望查询最新版本,还希望查询历史版本或快照。持久数据结构应运而生,它支持这些功能,尤其在函数式编程中得到了广泛研究。
持久认证字典(PADs)结合了这些特性,Anagnostopoulos等人引入了PADs,使用应用式(即函数式或无突变)的红黑树和跳表,每次更新需要 $O(log n)$ 的存储空间。
2. 定义和模型
我们专注于对存储在不可信服务器上的动态集合进行集合成员和非成员查询的认证。为防止服务器对存储的数据说谎,作者会包含认证信息,以便验证查找响应。
认证字典支持普通字典操作,如插入
I(K, V)
和删除
D(K)
来更新内容。查找操作
L(K)
返回答案(如果键存在)或
null
(如果键不存在),以及结果正确性的成员证明
P
。服务器必须证明给定的查询结果与某些外部数据一致,如作者对树的根哈希的签名。
当认证字典允许作者对字典内容进行快照时,它就成为了持久认证字典。查询可以针对当前版本或任何历史快照。理想情况下,PADs 能高效存储所有快照,可能会在不同快照之间共享状态。
2.1 威胁模型
我们对加密原语的安全性做出了典型假设。假设拥有理想化的加密单向哈希函数(即不会发生碰撞,且无法从输出推导出输入),公钥密码系统的语义也类似理想化。还假设存在可信的公钥基础设施(PKI)或其他方式来识别与作者关联的公钥。
考虑一个包含三方的信任模型:
- 可信作者:存储有限,可能间歇性连接。
- 不可信服务器:存储量大,持续在线连接。
- 多个客户端:执行查询,存储有限。
作者要求服务器插入或删除(键,值)对,并提供必要的认证信息。客户端联系服务器时,会验证结果证明,包括验证服务器数据结构的一致性和作者的数字签名。
我们还考虑了 PAD 作者不可信的情况,这在各种财务审计和监管合规场景中很重要。例如,作者可能恶意更改 PAD 的过去值,可能与服务器勾结;或者作者负责收集和汇总记录,如银行账户和余额列表,并试图行为不当。幸运的是,如果作者签署不一致的答案或不正确地汇总记录,其不当行为可以被客户端和审计人员发现。
2.2 特性
认证字典(持久或非持久)可能支持许多特性,以下是我们研究的字典支持的特性:
| 特性 | 描述 |
| ---- | ---- |
| 超高效性 | 查找请求返回的证明大小是固定的。基于元组的 PADs 提供超高效性。 |
| 部分持久性 | 我们考虑的 PADs 实际上是部分持久的,即虽然可以查询认证字典的任何版本,但只有最新版本可以修改。我们提供两个额外操作:
S()
用于对字典的当前内容进行快照并返回版本号;
LV(K, Vnum)
用于在历史快照中查找与键关联的值(如果有),并返回结果正确性的证明
P
。为了简化成本评估,我们假设每次更新后都会进行快照。 |
| 历史无关性 | 一些数据结构可以隐藏其构建顺序的信息。例如,如果数据项按排序数组存储,则不会留下插入顺序的信息。历史无关性可以源于随机化,如 Micciancio 展示的 2 - 3 树,其结构取决于抛硬币,而不是键的插入顺序;也可以源于具有规范或唯一表示的数据结构。我们的数据结构是“集合唯一”的,即字典中的给定键集具有唯一且规范的表示。基于树的 PAD 设计和一些基于元组的 PADs 是历史无关的。在持久字典中,历史无关性意味着如果在两个相邻快照之间发生多次更新,客户端不会了解更新的顺序,服务器在批量接收更新时也不会了解任何信息。此外,客户端不能根据任何其他快照的查询响应了解某个快照中的键的任何信息。 |
| 聚合 | 任何树数据结构都可以包含汇总给定节点子节点的聚合信息(例如,捕获它们的最小值和最大值或它们的总和)。这些聚合信息本身很有价值,可用于搜索或其他应用。基于树的 PADs 支持聚合。 |
| 根认证器 | 对于每个快照,最好有一个单一的值来固定或提交该特定时间的整个字典。这个值可以由客户端高效存储和复制,存储在时间戳系统或防篡改日志中。根认证器简化了发现不可信作者或服务器是否对过去说谎的过程。不信任的客户端只需发现作者为同一快照签署了不同的根认证器,而无需深入查看。 |
3. 基于树的 PADs
我们可以使用平衡搜索树构建 PADs。基于树的 PADs 的成员证明大小、更新大小和成员证明验证时间与字典中的键数量呈对数关系。它们在查询时间和存储空间之间提供了一系列权衡。我们首先介绍构建基于树的 PADs 的三个组件:Merkle 树、Treap 和持久二叉搜索树,然后展示如何将它们组合起来。
3.1 Merkle 树
给定一个搜索树,每个节点包含键、值和两个子指针,我们可以通过构建 Merkle 树来构建认证字典。对于每个节点
x
,我们使用以下递归来分配子树认证器
x.H
:
x.H = H(x.key, H(x.val), x.left.H, x.right.H)
其中
H
表示加密哈希函数。根认证器
root.H
认证整棵树,可以由作者发布或签名。
Merkle 树还支持 Merkle 聚合功能,搜索树中的节点可以用额外的数据进行注释,这些数据可以在树中向上累积。例如,在银行交易日志中,注释可以是显著交易的标志、按总和聚合的美元值或按最小和最大边界聚合的时间间隔。为防止篡改,节点的注释包含在其父节点的子树认证器中。如果作者不可信,审计人员可以检查这些注释以验证作者的正确行为。
成员证明是证明键
kq
在树中的证据。它由包含到
kq
的搜索路径的修剪树组成。搜索路径上兄弟节点的子树认证器以及包含
kq
的节点的子节点的子树认证器也包含在证明中。从这个修剪树中,重建根认证器并与给定的根认证器进行比较。我们可以通过显示键原本应存储的唯一中序位置为空来证明键不在树中。
对于平衡搜索树,如果子树认证器预先计算,成员证明的大小为 $O(log n)$,并可以在 $O(log n)$ 时间内生成。传统的认证搜索树实现使用逻辑子树认证器缓存,将每个节点的子树认证器存储在节点本身中。需要注意的是,这个缓存是可选的,因为服务器可以从现有树中即时重新计算任何哈希。没有缓存时,生成成员证明需要 $O(n)$ 时间来重新计算省略子树的子树认证器。当然,缓存有明显的性能优势。
Merkle 聚合公式如下:
设节点
x
的子树聚合为
x.A
,
φ
是计算与键值对关联的注释的函数,
⊕
是聚合函数。定义
x.σ = H(x.H, x.A)
,则 Merkle 聚合可以描述为:
x.A = φ(x.key, x.val) ⊕ x.left.A ⊕ x.right.A
x.H = H(x.key, H(x.val), x.left.σ, x.right.σ)
无论主机以前在证明中存储或包含节点的哈希,现在都将包含节点的哈希和聚合,这些可以根据需要进行缓存或重新计算。
3.2 Treap
我们基于 Treap 构建基于树的字典,Treap 是一种随机化搜索树,实现了字典功能。插入、删除或查找的预期成本为 $O(log n)$。Treap 支持高效的集合并、差和交集操作。
每个 Treap 节点包含键、值、优先级以及左右子指针。节点遵循标准的搜索键顺序,即节点的键总是大于其左子树中的所有键,小于其右子树中的所有键。此外,每个节点的优先级遵循堆属性,即节点的优先级总是小于其后代的优先级。修改树的操作会执行旋转以保持优先级的堆属性。
当优先级随机分配时,生成的树将是概率平衡的。此外,给定节点的优先级分配,特定集合上的 Treap 是唯一的。我们通过创建确定性 Treap 来利用这种唯一性,使用键的加密摘要分配优先级,创建集合唯一的表示。
假设加密摘要是随机预言机,平均而言,每次插入和删除只修改 $O(1)$ 个节点,包括一个子指针被修改的节点和 $O(1)$ 次旋转。在 Treap 中查找键的预期路径长度为 $O(log n)$。
集合唯一表示的好处:
- 确定性 Treap 是集合唯一的,这意味着所有具有相同内容的认证字典具有相同的树结构。如果我们从这些 Treap 构建 Merkle 树,那么任何两个具有相同内容的认证字典将具有相同的根哈希。集合唯一性使我们的 Treap 具有历史无关性,根哈希不会泄露键的插入顺序或 Treap 的过去内容的信息,这在电子投票存储或零知识证明中很有价值。
- 历史无关性在分布式系统中存储或同步复制状态时也很有用。更新可能通过多播或八卦协议以无序方式到达副本。使用集合唯一的认证数据结构,我们可以高效地确定两个副本是否不一致。
- 历史无关性还使从备份中恢复或创建副本变得更容易。如果主机尝试从备份或另一个副本恢复字典内容,历史无关性确保恢复的字典具有相同的根哈希。如果使用非集合唯一的数据结构,如红黑树,原始字典和恢复时的不同插入顺序可能会导致即使恢复的字典内容相同,根哈希也不同。
3.3 持久二叉搜索树
持久搜索树数据结构扩展了普通搜索树数据结构,以支持对过去快照或版本的查找。Sarnak 和 Tarjan 提出了几种用于持久红黑搜索树的方法,我们将其技术应用于 Treap。
逻辑上,使用搜索树构建的持久字典是一个树森林,即每个快照对应一棵单独的树。每棵树的根存储在一个快照数组中,由快照版本索引。历史快照是冻结且不可变的,最新的或当前快照可以就地更新以包含插入或删除的键。每次进行快照时,会向快照数组中添加一个新的根,此后该快照不可变。
Sarnak 和 Tarjan 提出了三种表示逻辑森林的策略:
-
复制所有内容
:每次快照时复制整个 Treap,对于包含
n
个键的快照,需要 $O(n)$ 的存储空间。
-
路径复制
:使用标准的应用式 Treap,避免在不同快照之间重复存储相同的子树。路径复制 Treap 中的节点是不可变的。当普通的可变 Treap 算法会修改节点的子指针时,应用式 Treap 会创建一个具有新子指针的修改克隆节点。父节点也会被克隆,克隆节点指向新的子节点。这会一直传播到根,创建一个新的根。每次更新 Treap 会创建 $O(1)$ 个新节点和 $O(log n)$ 个克隆节点。如果每次更新后进行快照,每次更新的存储量为 $O(log n)$。
-
版本化节点
:暂未详细介绍。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(选择持久化策略):::process
B --> C{复制所有内容?}:::decision
C -->|是| D(复制整个Treap):::process
C -->|否| E{路径复制?}:::decision
E -->|是| F(创建修改克隆节点):::process
E -->|否| G(版本化节点策略):::process
D --> H(存储新快照):::process
F --> H
G --> H
H --> I([结束]):::startend
以上是关于持久认证字典的上半部分内容,涵盖了其基本概念、特性以及基于树的构建方法。下半部分将继续介绍超级高效的 PADs 设计、算法的预期运行时间以及未来工作和结论。
超高效聚合历史无关的持久认证字典
4. 超级高效的 PADs
在这部分,我们将基于不同的设计原则开发超级高效的 PADs,它能提供固定大小的认证结果,并且每次更新的存储量为常数。
我们提出的基于元组的 PADs 实现了超级高效性。这种设计的核心在于让查找请求返回的证明大小为常数。与基于树的 PADs 不同,元组 PADs 采用了一种独特的方式来存储和验证数据。
在元组 PADs 中,数据以元组的形式组织。每个元组包含键、值以及相关的认证信息。当进行查找操作时,系统会根据特定的算法从这些元组中提取所需的信息,并生成一个固定大小的证明。这个证明包含了足够的信息,使得客户端能够验证查询结果的正确性,而无需依赖于复杂的树结构和大量的子树认证器。
例如,假设我们有一个包含多个元组的集合,每个元组表示一个键值对及其认证信息。当客户端发起一个查找请求时,系统会根据键在元组集合中进行查找。一旦找到匹配的元组,系统会从该元组以及相关的辅助信息中生成一个固定大小的证明。这个证明可以是一个简单的哈希值或者一个包含特定信息的加密字符串。
客户端接收到证明后,会使用预先存储的根认证器或者其他认证信息来验证证明的有效性。由于证明大小固定,无论字典中的数据量有多大,验证过程的复杂度都是恒定的,从而实现了超级高效的查找和验证。
部分元组 PADs 还具备历史无关性。这意味着即使在不同的时间点进行了多次更新,客户端也无法从查询结果中推断出更新的顺序。这种特性在保护数据隐私和防止信息泄露方面具有重要意义。
| PADs 类型 | 证明大小 | 每次更新存储量 | 历史无关性 |
|---|---|---|---|
| 基于树的 PADs | $O(log n)$ | 多种情况 | 部分具备 |
| 基于元组的 PADs | 常数 | 常数 | 部分具备 |
5. 算法的预期运行时间
接下来,我们总结一下所提出算法的预期运行时间。这有助于我们评估不同设计的性能,为实际应用提供参考。
| 操作 | 基于树的 PADs | 基于元组的 PADs |
|---|---|---|
| 插入 | $O(log n)$ | 常数 |
| 删除 | $O(log n)$ | 常数 |
| 查找 | $O(log n)$ | 常数 |
| 快照 |
$O(log n)$(路径复制)
$O(n)$(复制所有内容) | 常数 |
从表格中可以看出,基于树的 PADs 在插入、删除和查找操作上的时间复杂度为 $O(log n)$,这是由于树结构的特性决定的。在进行快照操作时,不同的持久化策略会导致不同的时间复杂度。例如,路径复制策略每次更新需要 $O(log n)$ 的时间,而复制所有内容策略则需要 $O(n)$ 的时间。
相比之下,基于元组的 PADs 在插入、删除、查找和快照操作上都能达到常数时间复杂度。这使得基于元组的 PADs 在处理大量数据和频繁更新的场景下具有明显的性能优势。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(选择操作类型):::process
B --> C{插入?}:::decision
C -->|是| D(基于树的PADs: O(log n)):::process
C -->|否| E{删除?}:::decision
E -->|是| F(基于树的PADs: O(log n)):::process
E -->|否| G{查找?}:::decision
G -->|是| H(基于树的PADs: O(log n)):::process
G -->|否| I{快照?}:::decision
I -->|是| J{路径复制?}:::decision
J -->|是| K(基于树的PADs: O(log n)):::process
J -->|否| L(基于树的PADs: O(n)):::process
D --> M(基于元组的PADs: 常数):::process
F --> M
H --> M
K --> M
L --> M
M --> N([结束]):::startend
这个流程图展示了不同操作在基于树的 PADs 和基于元组的 PADs 中的时间复杂度情况。可以清晰地看到,基于元组的 PADs 在各种操作上都具有更优的时间性能。
6. 未来工作和结论
虽然我们已经提出了多种高效的 PADs 设计,但仍有一些方面值得进一步研究和改进。
在未来工作中,我们计划对现有的设计进行优化,以提高其在不同场景下的性能。例如,进一步研究如何减少元组 PADs 在生成固定大小证明时的计算开销,提高其在大规模数据存储中的效率。
我们还将探索更多的应用场景,将 PADs 技术推广到更多领域。例如,在金融领域,可以利用 PADs 的安全性和高效性来存储和验证交易记录;在医疗领域,可以用于保护患者的隐私数据,确保数据的完整性和可追溯性。
还需要加强对 PADs 的安全性分析。随着技术的发展,新的安全威胁可能会不断出现。我们需要不断评估和改进 PADs 的安全机制,以应对各种潜在的攻击。
我们提出的持久认证字典(PADs)为数据的安全存储和验证提供了一种有效的解决方案。基于树的 PADs 和基于元组的 PADs 各有优势,它们在不同的场景下可以发挥出最佳性能。基于树的 PADs 在支持聚合和集合操作方面表现出色,而基于元组的 PADs 则实现了超级高效性和固定大小的认证结果。通过合理选择和应用这些设计,我们可以满足不同用户对数据安全和性能的需求。在未来的研究中,我们将继续努力,不断完善 PADs 技术,为更多领域的应用提供有力支持。
超级会员免费看
32

被折叠的 条评论
为什么被折叠?



