2个稳定版本
1.9.0 | 2023年6月13日 |
---|---|
1.8.0 | 2023年6月13日 |
#465 在 数学
4,559 每月下载量
425KB
9K SLoC
Rust uint
crate使用const泛型
实现 [Uint<BITS, LIMBS>
],模$2^{\mathsf{BITS}}$的数环。它需要两个泛型参数:存储这些位所需的位数和64位'limb'的数量。
# use ruint2::Uint;
let answer: Uint<256, 4> = Uint::from(42);
您可以使用 $\mathsf{LIMBS} = \left\lceil{\mathsf{BITS} / 64\right\rceil}$ 自己计算 LIMBS
。如果使用不正确的参数构建,Uint
将会引发恐慌。理想情况下,这应该是一个编译时错误,但由于Rust问题 #76560,这被阻止了。
在稳定版本中,您可以使用更方便的方法uint!
,该宏会为您构建正确的Uint
。
# use ruint2::{Uint, uint};
let answer = uint!(42_U256);
您还可以使用预定义的类型别名aliases
# use ruint2::Uint;
use ruint2::aliases::*;
let answer: U256 = Uint::from(42);
当然,如果您需要特殊大小的类型别名,您也可以创建自己的类型别名
# use ruint2::Uint;
type U1337 = Uint<1337, 21>;
let answer: U1337 = Uint::from(42);
Rust nightly
如果您使用的是nightly版本,可以使用Uint<BITS>
,它会为您计算 limb 的数量。不幸的是,没有 generic_const_exprs
的支持,无法将其稳定化(Rust问题 #76560)。
# #[cfg(has_generic_const_exprs)] {
use ruint2::nightly::Uint;
let answer: Uint<256> = Uint::<256>::from(42);
# }
即使在夜间版本,Rust 的用户体验仍受到限制。在上面的例子中,Rust 要求对 Uint::from
进行显式类型标注,而在稳定版本中则不需要。还有一些更微妙的问题使得它看起来并不那么理想。这些夜间功能可能还需要一段时间才能稳定。
示例
use ruint2::Uint;
let a: Uint<256, 4> = Uint::from(0xf00f_u64);
let b: Uint<256, 4> = Uint::from(42_u64);
let c = a + b;
assert_eq!(c, Uint::from(0xf039_u64));
有一个方便的宏 uint!
可以为您创建常量。它允许使用标准 Rust 整数语法创建任意长度的常量。`Uint` 或 `Bits` 的大小由一个以数字开头的 `U` 或 `B` 后缀指定。支持十进制、十六进制,甚至二进制和八进制标准 Rust 语法,使用它们的 0x
、0b
和 0o
前缀。为了可读性,可以在字面量中添加下划线 _
。
# use ruint2::uint;
let cow = uint!(0xc85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4_U256);
实际上,这个宏会递归地解析语法树,因此您可以将其应用于整个源文件。
# use ruint2::uint;
uint!{
let a = 42_U256;
let b = 0xf00f_1337_c0d3_U256;
let c = a + b;
assert_eq!(c, 263947537596669_U256);
}
请注意,由于 B
是一个有效的十六进制数字,因此可能会产生歧义。在这种情况下,需要一个下划线分隔符 _B
来减少影响。
功能标志
支持许多 crate。这些功能可以通过设置同名功能标志来启用。
unstable
启用 sem-ver 不稳定功能。rand
:实现了从Standard
分布中采样的功能,即rng.gen()
。arbitrary
:实现了Arbitrary
特性,允许为模糊测试生成Uint
。quickcheck
:实现了Arbitrary
特性,允许为基于属性的测试生成Uint
。proptest
:实现了Arbitrary
特性,允许为基于属性的测试生成Uint
。Proptest 用于uint
的测试套件。serde
:为Serialize
和Deserialize
特性实现了Uint
和Bits
。序列化使用大端十六进制的人可读格式和在大端字节字符串的机器可读格式。在可读格式中序列化时,Uint
使用以太坊Quantity
格式(以0x为前缀的最小字符串)。rlp
:为Uint
实现了Encodable
和Decodable
特性,以允许从/到 RLP 的序列化。fastrlp
:为Uint
实现了Encodable
和Decodable
特性,以允许从/到 RLP 的序列化。primitive-types
:实现了相应类型之间的From<_>
转换。postgres
:实现了支持许多列类型的ToSql
特性。num-bigint
:实现了与BigUint
和BigInt
之间的转换。ark-ff
:实现了与BigInt
和Fp
类型之间的转换。sqlx
:实现作为字节数组的数据库无关存储。由于问题 sqlx#1627,需要与sqlx
一起使用tokio-native-tls
运行时。zeroize
:实现了Zeroize
特性。这使得Uint
和Bits
与secrecy
包兼容。valuable
:实现了Valuable
特性。pyo3
:实现了ToPyObject
、IntoPy
和FromPyObject
特性。parity-scale-codec
:实现了Encode
、Decode
、MaxEncodedLen
和HasCompact
特性。bn-rs
:实现了从/到BN
和BigNumber
的转换。
构建和测试
格式化、检查代码风格、构建和测试所有内容(建议创建一个shell别名)
cargo fmt &&\
cargo clippy --all-features --all-targets &&\
cargo test --workspace --all-features --doc -- --nocapture &&\
cargo test --workspace --all-features --all-targets -- --nocapture &&\
cargo doc --workspace --all-features --no-deps
使用提供的 .cargo/config.toml
别名运行基准测试
cargo criterion
检查文档覆盖率
RUSTDOCFLAGS="-Z unstable-options --show-coverage" cargo doc --workspace --all-features --no-deps
特性
- 所有希望拥有的生活品质特性。
- 与 std
u64
等类型兼容。参见Rust的 整数方法。 - 遵循 Rust API指南
- Montgomery REDC和其他算法,用于实现素数域。
待办事项
- 构建
no-std
和wasm
。 - 快速的平台无关的泛型算法。
- 针对特定平台进行汇编优化(如果可用)。
- 可选的 num-traits 等,支持。
- 运行时大小类型,具有兼容的接口。
依赖项
~0.3–16MB
~218K SLoC