【问题标题】:Distributing blocks with validation and non-dependant list generation分发具有验证和非依赖列表生成的块
【发布时间】:2013-05-30 19:46:06
【问题描述】:

问题
假设我有一个可以与父节点通信但不能相互通信的节点系统。假设然后父节点上的文件被分成块并在子节点之间划分。然后从父节点中删除该文件。

如果父级随后向子级请求块,如何在不保留父级上所有文件的列表的情况下重建原始顺序。此外,为了防止其中一个节点恶意修改区块,父节点还必须验证返回的区块。

最佳解决方案
命名文件块的系统,其中文件列表可以在给定种子的任何节点上生成。给定列表,父母应该能够以某种方式使用该列表来验证从孩子返回的块。

尝试 #1
所以到目前为止我所拥有的是能够最小化存储块列表的能力。我通过这样命名块来做到这一点:

block_0 = hash(file_contents)
block_n = hash(block_n-1) [hashing the name of the previous file]

这可以通过仅保留种子(block_0 的名称)和块数(例如 5d41402abc4b2a76b9719d911017c592,5 --> seed,files)来保留文件的顺序。但是,这将不允许独立验证文件。

尝试 #2
只需获取每个块的哈希并将其存储在列表中。然而,这效率不高,如果需要跟踪大量块,将导致仅为此任务分配大量内存。这样不行。

【问题讨论】:

    标签: graph tree cryptography distributed cryptographic-hash-function


    【解决方案1】:

    我不确定我是否遇到了问题,但我想这是一个可能的解决方案:

           | Distribution:
    parent | buffer = [hash(key, id)), data[id]]; send(buffer);
    nodes  | recv(buffer); h_id, data = buffer;
    

    父节点使用一些本地key 为其发送的数据的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
    

    由于key 仅在父节点中已知,本地节点很难更改data 和 h_id,使得hash(key, data_id) 在父节点,仍然有效。

    关于排序,您可以简单地假设data 的四个初始字节存储分区的编号——以供以后重建。

    编辑:

    我可能没有注意到您指出的这个额外存储,但这是我试图提出的。考虑四台机器,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]。此外,如果您允许每台机器存储/接收key,您以后可以un 散列data[i] 并在每个本地节点上重建data[3]。

    注意添加错误只能发生在数据分片data[i] 和收到的密钥hash(key, data[i]) 上,因为您必须假设key 是全局有效的。这里的要点是hash(key, data[i]) 值的列表也分布在机器之间,而不仅仅是数据分区本身,即您不需要包含所有文件的列表单独存储在任何机器中.

    考虑到您有能力在每个节点中维护key,或者至少将key 发送到尝试重建原始数据的一个节点,这里有一个减少步骤的示例,例如,对于节点@987654352 @。 A 和 C 将它们的本地 {data[i], hash(key, data[i])} 发送到节点 B,P 将 key 发送到 B,因此该节点可以un对接收到的数据进行哈希处理:

                                 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 我并没有真正了解您指出的 listing 过程;我试图澄清我的建议,尽管我可能仍然缺少你指出的这个额外的存储空间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多