4个版本
0.2.0 | 2023年2月27日 |
---|---|
0.1.2 | 2023年2月15日 |
0.1.1 | 2023年2月15日 |
0.1.0 | 2023年2月14日 |
#781 in 加密学
1,588 每月下载次数
145KB
2K SLoC
这是对https://github.com/oconnor663/bao的分支,增加了异步支持和块组。
块组
作为原始bao crate的扩展,这个crate实现了块组。块组可以通过(互斥)功能标志来选择。
支持的块组从1kb(每个组1个块,与原始bao crate兼容)到1024kb(每个组2^10个块)。
默认为16kb,即每个组2^4个块。
Bao是实现BLAKE3验证流的一个版本,如BLAKE3规范第6.4节所述。BLAKE3这样的树哈希使得验证文件的一部分而无需重新哈希整个文件成为可能,使用一种编码格式来存储文件的字节以及其哈希树的所有节点。客户端可以流式传输这种编码,或在其中进行随机查找,同时验证它们读取的每个字节都与根哈希匹配。关于其工作原理的详细信息,请参阅Bao规范。
本项目包含两个Rust包,分别是bao
库包和bao_bin
二进制包。后者提供了bao
命令行工具。
注意! Bao是beta版加密软件。它尚未经过正式审计。
编码和解码
用例:一个安全的消息应用可能通过在消息元数据中包含附件的哈希值来支持附件文件。使用序列哈希,接收者需要下载整个附件来验证它,但对于像大型视频文件这样的东西来说可能不太实际。使用BLAKE3和Bao,接收者可以流式传输视频附件,同时验证每个字节的到来。(这是Bao项目的原始动机。)
# Create an input file that's a megabyte of random data.
> head -c 1000000 /dev/urandom > f
# Convert it into a Bao encoded file.
> bao encode f f.bao
# Compare the size of the two files. The encoding overhead is small.
> stat -c "%n %s" f f.bao | column -t
f 1000000
f.bao 1062472
# Compute the BLAKE3 hash of the original file. The `b3sum` tool would
# also work here.
> hash=`bao hash f`
# Stream decoded bytes from the encoded file, using the hash above.
> bao decode $hash < f.bao > f2
> cmp f f2
# Observe that using the wrong hash to decode results in an error. This
# is also what will happen if we use the right hash but corrupt some
# bytes in the encoded file.
> bad_hash="0000000000000000000000000000000000000000000000000000000000000000"
> bao decode $bad_hash < f.bao
Error: Custom { kind: InvalidData, error: StringError("hash mismatch") }
验证切片
编码文件支持随机查找,但通过网络查找可能不可用或效率不高。(注意,内容中的每次查找通常需要在编码中查找几次,因为解码器逐级遍历哈希树。)在这些情况下,与其尝试远程查找,客户端可以请求包含所需内容字节的编码切片。创建切片需要发送者在整个编码中查找,但接收者可以流式传输切片而不进行任何查找。解码切片使用与常规解码相同的根哈希,因此不需要发送者或接收者在事先进行任何准备。
用例:一个类似BitTorrent的应用程序可以从不用的节点获取文件的不同切片,而无需事先定义切片。或者一个分布式文件存储应用程序可以从其存储提供商请求归档文件的随机切片,以证明它们诚实地存储了文件,而无需准备或存储未来的挑战。
# Using the encoded file from above, extract a 100 KB slice from
# somewhere in the middle. We'll use start=500000 (500 KB) and
# count=100000 (100 KB).
> bao slice 500000 100000 f.bao f.slice
# Look at the size of the slice. It contains the 100 KB of content plus
# some overhead. Again, the overhead is small.
> stat -c "%n %s" f.slice
f.slice 107272
# Using the same parameters we used to create the slice, plus the same
# hash we got above from the full encoding, decode the slice.
> bao decode-slice $hash 500000 100000 < f.slice > f.slice.out
# Confirm that the decoded output matches the corresponding section from
# the input file. (Note that `tail` numbers bytes starting with 1.)
> tail --bytes=+500001 f | head -c 100000 > expected.out
> cmp f.slice.out expected.out
# Now try decoding the slice with the wrong hash. Again, this will fail,
# as it would if we corrupted some bytes in the slice.
> bao decode-slice $bad_hash 500000 100000 < f.slice
Error: Custom { kind: InvalidData, error: StringError("hash mismatch") }
外设模式
默认情况下,上述所有操作都使用“组合”编码文件,即包含内容字节和树哈希字节交织在一起的文件。但是,有时您希望将它们分开,例如避免重复一个非常大的输入文件。在这些情况下,您可以使用“外设”编码格式,通过--outboard
标志
# Re-encode the input file from above in the outboard mode.
> bao encode f --outboard f.obao
# Compare the size of all these files. The size of the outboard file is
# equal to the overhead of the original combined file.
> stat -c "%n %s" f f.bao f.obao | column -t
f 1000000
f.bao 1062472
f.obao 62472
# Decode the whole file in outboard mode. Note that both the original
# input file and the outboard encoding are passed in as arguments.
> bao decode $hash f --outboard f.obao f4
> cmp f f4
安装和从源码构建
bao
命令行工具作为bao_bin
包发布在crates.io上。要安装它,将~/.cargo/bin
添加到您的PATH
中,然后运行
cargo install bao_bin
从本仓库直接构建二进制文件
git clone https://github.com/oconnor663/bao
cd bao/bao_bin
cargo build --release
./target/release/bao --help
tests/bao.py
是Python中完全功能性的第二实现,设计得尽可能短和易读。它是理解涉及的算法的好起点,在深入研究Rust代码之前。
依赖关系
~1.3–2.8MB
~61K SLoC