Graph 使用验证和非依赖列表生成分发块
问题Graph 使用验证和非依赖列表生成分发块,graph,tree,cryptography,distributed,cryptographic-hash-function,Graph,Tree,Cryptography,Distributed,Cryptographic Hash Function,问题 假设我有一个节点系统,它可以与父节点通信,但不能相互通信。假设父节点上的一个文件被分割成块并在子节点之间分割。然后从父节点删除该文件 如果父对象随后请求从子对象返回块,那么如何在不保留父对象上所有文件的列表的情况下重建原始顺序。此外,为了防止其中一个节点恶意修改块,父节点还必须验证返回的块 最佳解决方案 一种命名文件块的系统,其中可以在给定种子的任何节点上生成文件列表。给定该列表,父级应该能够以某种方式使用该列表来验证从子级返回的块 尝试#1 因此,到目前为止,我得到的是能够最小限度地存储
假设我有一个节点系统,它可以与父节点通信,但不能相互通信。假设父节点上的一个文件被分割成块并在子节点之间分割。然后从父节点删除该文件 如果父对象随后请求从子对象返回块,那么如何在不保留父对象上所有文件的列表的情况下重建原始顺序。此外,为了防止其中一个节点恶意修改块,父节点还必须验证返回的块 最佳解决方案
一种命名文件块的系统,其中可以在给定种子的任何节点上生成文件列表。给定该列表,父级应该能够以某种方式使用该列表来验证从子级返回的块 尝试#1
因此,到目前为止,我得到的是能够最小限度地存储一个块列表。为此,我将块命名为:
block_0 = hash(file_contents)
block_n = hash(block_n-1) [hashing the name of the previous file]
这样,只需保留种子(块的名称_0)和块的数量(例如5d41402abc4b2a76b9719d911017c592,5-->种子,文件),即可保留文件的顺序。但是,这将不允许独立验证文件
尝试#2只需获取每个块的散列并将其存储在列表中即可。但是,这不是有效的,如果需要跟踪大量的块,将导致单独为此任务分配大量内存。这不行。我不确定是否有问题,但我想这是一个可能的解决方案:
| Distribution:
parent | buffer = [hash(key, id)), data[id]]; send(buffer);
nodes | recv(buffer); h_id, data = buffer;
父节点使用一些本地键
为其发送的id
部分数据生成散列值(h_id
),本地节点将接收生成的h_id
和数据本身
| Reduction:
nodes | buffer = [h_id, data]; send(buffer);
parent | recv(buffer); h_id, data_id = buffer;
在计数器流上,节点必须发送原始h_id
和以前接收的数据,否则,以下验证将失败:
hash(key, data) == h_id
由于键
仅在父节点中已知,因此本地节点很难改变数据
和h\u id
,从而使得父节点中的散列(键,数据\u id)
仍然有效
关于排序,您可以简单地假设数据的四个初始字节存储分区的编号,以便以后重建
编辑:
我可能没有注意到你所指的额外存储空间,但以下是我试图提出的建议。考虑四台机器,<代码> A/<代码> <代码> B<代码> >代码> C>代码>和<代码> P<代码>,初始数据:
P{key, data[3]}
____|____
/ | \
A{} B{} C{}
然后,p
在机器之间分配数据,同时发送数据碎片本身,和生成的哈希:
P{key, data[3]}
____|____
/ | \
A | C
{data[0], hash(key, data[0])} | {data[2], hash(key, data[2])}
B
{data[1], hash(key, data[1])}
如果假设data[i]
中的第一个字节存储了一个全局索引,则可以按原始顺序重建初始基data[3]
。此外,如果您允许每台计算机存储/接收密钥
,则以后可以在每个本地节点上解散列数据[i]
并重建数据[3]
请注意,错误的添加只能发生在数据碎片data[i]
和接收到的密钥hash(key,data[i])
上,因为您必须假设密钥
是全局有效的。这里的要点是散列(key,data[i])
值的列表也分布在机器之间,而不仅仅是数据分区本身,也就是说,您不需要在任何机器中单独存储所有文件的列表
考虑到您可以在每个节点中维护key
,或者至少向尝试重建原始数据的节点发送key
,下面是一个简化步骤的示例,例如,对于节点B
A
和C
将其本地{data[i],散列(key,data[i])}
发送到节点B
,而P
将key
发送到B
,因此此节点可以取消对接收到的数据的散列:
P{key, data[3]}
|
A | C
{data[0], hash(key, data[0])} | {data[0], hash(key, data[0])}
\ | /
B
{data[1], hash(key, data[1])}
然后,B
计算:
/ {data[1], hash(key, data[1])} \ {data[1]}
unhash( {data[0], hash(key, data[0])} ) => {data[0]} => {data[3]}
\ {data[2], hash(key, data[2])} / {data[2]}
它以正确的顺序还原原始数据。这是一个良好的开端,因为它确实对校验和进行了签名,但这与我的第二次尝试没有区别,因为它需要存储所有文件的列表。有没有一种方法可以实现这一点,从而可以在任何节点(包括父节点)上以最少的信息生成它。关于我的意思,请参见尝试1。谢谢@MattOlan我没有真正了解你所指的上市流程;我试图澄清我的提议,尽管我可能仍然错过了你提到的额外存储空间。