8个版本 (5个重大更改)
0.7.1 | 2024年3月9日 |
---|---|
0.6.0 | 2024年3月7日 |
0.1.5 |
|
0.1.4 |
|
在 密码学 中排名 #404
在 3 个crate中使用 (2个直接使用)
51KB
975 行
gitoid
crate
该crate实现了Rust中的GitOid
,Git对象标识符。该crate由OmniBOR项目创建和维护,主要用于该项目的用例。
用法
该crate的关键类型是GitOid
,它由两个特质:HashAlgorithm
和ObjectType
参数化。这两个都是密封特质,这意味着它们只可由gitoid
crate中找到的类型实现。要使用GitOid
类型,您必须提供这些类型参数,如下所示
use gitoid::{GitOid, Sha256, Blob};
fn main() {
let id = GitOid::<Sha256, Blob>::from_str("hello, world");
println!("{}", id);
}
如果您打算只使用GitOid
类型的特定实例化,您可以使其更简洁,如下所示
use gitoid::{Sha256, Blob};
type GitOid = gitoid::GitOid<Sha256, Blob>;
fn main() {
let id = GitOid::from_str("hello, world");
println!("{}", id);
}
设计
该crate旨在限制GitOid
类型在内存中的大小,并将尽可能多的工作放在编译时。为此,GitOid
类型使用通用的数组来确保存储缓冲区的大小正好与所需存储所选哈希算法输出的哈希值的字节数相匹配。哈希算法和对象类型信息也通过在GitOid
类型上的方法调用在编译时连接起来,这样它们就可以在运行时访问,而无需实际存储在每个GitOid
实例上。
Git兼容性
该crate实际上以两种有意义的方式与Git处理对象标识符的方式不同。
-
在
gitoid
crate和git
本身中,GitOIDs的内存表示不同。在Git中,相关类型称为object_id
,如下定义:定义如下struct object_id { unsigned char hash[GIT_MAX_RAWSZ]; int algo; /* XXX requires 4-byte alignment */ };
此类包含一个缓冲区,大小足以存储Git支持的最大的哈希所需的字节数(目前为SHA-256所需的32字节),以及一个用于指示所选哈希算法的整数。在哈希输出小于32字节的哈希算法(如SHA-1)的情况下,这会降低效率,并且也意味着算法选择被委托给了运行时。它还在类型级别或嵌入式数据中无法区分Git用于标识的四个对象类型:blob(文件)、提交、标签和tree(目录)。对象类型通过生成哈希的输入的标准格式化规则来处理(这我们称之为“GitOID哈希构造”)。
因此,这种表示方法的空间效率低于可能的情况,并且为了支持基于哈希函数输入构造的隐式类型而省略了一些信息(对象类型)。
相比之下,在
gitoid
crate中,我们运行时只存储一个大小恰好与所选哈希函数生成的哈希输出所需的字节数相等的缓冲区,并使用零成本编译时特性来编码哈希算法和对象类型。我们目前没有实现除
blob
之外的对象类型的处理,因为这就是OmniBOR项目所需要的一切,我们非常愿意在未来添加对tree
、commit
和tag
的支持。 -
Git项目提到Git对象ID可以使用SHA-1哈希算法或SHA-256完成,但实际上并不完全是这样。SHA-1算法已被证明是有缺陷的,攻击者可以引发碰撞,为了限制这种破坏的影响,Git默认使用SHA-1的一个变体,称为SHA-1CD(简称“带有碰撞检测的SHA-1”)。该算法检查正在被哈希的数据是否存在某些产生碰撞的数据向量,如果检测到这些向量,它会以阻止碰撞发生的方式修改哈希。
对于Git的目的,这个善意的谎言是可以容忍的,因为ID永远不会在Git之外使用,但对于OmniBOR来说,我们关心对构造的准确性,因为ID的目的是由任何人独立再现。
因此,在这个crate中,我们区分了
sha1
算法和sha1cd
算法。这反映在使用GitOid
类型时生成的gitoid
-scheme URL中。
最低支持的Rust版本(MSRV)
这个crate没有维护最低支持的Rust版本,通常跟踪最新的Rust稳定版本。
许可证
此crate使用Apache 2.0许可证。
依赖关系
~1.4–3.5MB
~89K SLoC