Crate ruint
Expand description
§Rust uint
crate using const-generics
Implements Uint<BITS, LIMBS>
, the ring of numbers modulo $2^{\mathsf{BITS}}$. It requires two
generic arguments: the number of bits and the number of 64-bit ‘limbs’ required to store those bits.
let answer: Uint<256, 4> = Uint::from(42);
You can compute LIMBS
yourself using $\mathsf{LIMBS} = \left\lceil{\mathsf{BITS} / 64}\right\rceil$,
i.e.LIMBS
equals BITS
divided by $64$ rounded up. Uint
will panic!
if you try to
construct it with incorrect arguments. Ideally this would be a compile time error, but
that is blocked by Rust issue #60551.
A more convenient method on stable is to use the [uint!
] macro, which constructs the right
Uint
for you.
let answer = uint!(42_U256);
You can also use one of the pre-computed type aliases
:
use ruint::aliases::*;
let answer: U256 = Uint::from(42);
You can of course also create your own type alias if you need a funny size:
type U1337 = Uint<1337, 21>;
let answer: U1337 = Uint::from(42);
§Rust nightly
If you are on nightly, you can use [Uint<BITS>
][nightly::Uint] which will
compute the number of limbs for you. Unfortunately this can not be made stable
without generic_const_exprs
support (Rust issue #76560).
use ruint::nightly::Uint;
let answer: Uint<256> = Uint::<256>::from(42);
Even on nightly, the ergonomics of Rust are limited. In the example above Rust
requires explicit type annotation for Uint::from
, where it did not require
it in the stable version. There are a few more subtle issues that make this
less ideal than it appears. It also looks like it may take some time before
these nightly features are stabilized.
§Examples
use ruint::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));
There is a convenient macro [uint!
] to create constants for you. It allows
for arbitrary length constants using standard Rust integer syntax. The size of
the Uint
or Bits
is specified with a U
or B
suffix followed by the
number of bits. The standard Rust syntax of decimal, hexadecimal and even binary and octal is
supported using their prefixes 0x
, 0b
and 0o
. Literals can have
underscores _
added for readability.
let cow = uint!(0xc85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4_U256);
In fact, this macro recurses down the parse tree, so you can apply it to entire source files:
uint!{
let a = 42_U256;
let b = 0xf00f_1337_c0d3_U256;
let c = a + b;
assert_eq!(c, 263947537596669_U256);
}
Note that since B
is a valid hexadecimal digit there can be ambiguity. To lessen the impact an underscore separator _B
is required in this case.
§Supported Rust Versions
Uint will keep a rolling MSRV (minimum supported rust version) policy of at least 6 months. When increasing the MSRV, the new Rust version must have been released at least six months ago. The current MSRV is 1.65.0.
Note that the MSRV is not increased automatically, and only as part of a minor release.
§Feature flags
There is support for a number of crates. These are enabled by setting the identically named feature flag.
unstable
Enable sem-ver unstable features.rand
: Implements sampling from theStandard
distribution, i.e.rng.gen()
.arbitrary
: Implements theArbitrary
trait, allowingUint
s to be generated for fuzz testing.quickcheck
: Implements theArbitrary
trait, allowingUint
s to be generated for property based testing.proptest
: Implements theArbitrary
trait, allowingUint
s to be generated for property based testing. Proptest is used for theuint
s own test suite.serde
: Implements theSerialize
andDeserialize
traits forUint
andBits
.Serialization uses big-endian hex in human readable formats and big-endian byte strings in machine readable formats.Uint
uses ethereumQuantity
format (0x-prefixed minimal string) when serializing in a human readable format.rlp
: Implements theEncodable
andDecodable
traits forUint
to allow serialization to/from RLP.fastrlp
: Implements theEncodable
andDecodable
traits forUint
to allow serialization to/from RLP.primitive-types
: Implements theFrom<_>
conversions between corresponding types.postgres
: Implements theToSql
trait supporting many column types.num-bigint
: Implements conversion to/fromBigUint
andBigInt
.ark-ff
: Implements conversion to/from theBigInteger*
types and theFp*
types fromark-ff@0.3
.ark-ff-04
: Implements conversion to/fromBigInt
andFp
types fromark-ff@0.4
.sqlx
: Implements database agnostic storage as byte array. Requiressqlx
to be used with thetokio-native-tls
runtime, due to issue sqlx#1627.zeroize
: Implements theZeroize
trait. This makesUint
andBits
compatible with thesecrecy
crate.valuable
: Implements theValuable
trait.pyo3
: Implements theToPyObject
,IntoPy
andFromPyObject
traits.parity-scale-codec
: Implements theEncode
,Decode
,MaxEncodedLen
andHasCompact
traits.bn-rs
: Implements conversion to/from theBN
andBigNumber
.bytemuck
: Implements thePod
andZeroable
traits forUint
where the size is a multiple of 64, up to 1024. This allowsUint
to be used where aPod
trait bound exists.num-traits
: Implements about forty applicable traits.subtle
: Implements [Uint::bit_ct
],ConditionallySelectable
,ConditionallyNegatable
,ConstantTimeEq
/ConstantTimeGreater
/ConstantTimeLess
.der
: ImplementsEncode
/Decode
andTryFrom
/From
casting forAny
,AnyRef
,Int
,IntRef
,Uint
,UintRef
.diesel
: Implements theToSql
andFromSql
traits for storingUint
values as byte arrays in databases supported by Diesel.
§Building and testing
Format, lint, build and test everything (I recommend creating a shell alias for this):
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
Run benchmarks with the provided .cargo/config.toml
alias
cargo criterion
Check documentation coverage
RUSTDOCFLAGS="-Z unstable-options --show-coverage" cargo doc --workspace --all-features --no-deps
§Features
- All the quality of life features one could want.
- Compatible with std
u64
, etc types. See Rust’s integer methods. - Adhere to Rust API Guidelines
- Montgomery REDC and other algo’s for implementing prime fields.
§To do
- Builds
no-std
andwasm
. - Fast platform agnostic generic algorithms.
- Target specific assembly optimizations (where available).
- Optional num-traits, etc, support.
- Run-time sized type with compatible interface.
Modules§
- ⚠️ Collection of bignum algorithms.
- Support for external crates.
Macros§
- Compile time for loops with a
const
variable for testing.
Structs§
- A newtype wrapper around
Uint
that restricts operations to those relevant for bit arrays. - The ring of numbers modulo $2^{\mathtt{BITS}}$.
Enums§
- Error for
from_base_le
andfrom_base_be
. - Error for
TryFrom<Uint>
. - Error for
from_str_radix
. - Error for
TryFrom<Uint>
forark_ff
and others. - Error for
TryFrom<T>
forUint
.
Traits§
- ⚠️ Workaround for Rust issue #50133. Use
TryFrom
instead. - ⚠️ Workaround for Rust issue #50133. Use
TryFrom
instead.
Functions§
- Mask to apply to the highest limb to get the correct number of bits.
- Number of bytes required to represent the given number of bits.
- Number of
u64
limbs required to represent the given number of bits. This needs to be public because it is used in theUint
type.