crypto_bigint/lib.rs
1#![no_std]
2#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7)]
8#![deny(unsafe_code)]
9#![warn(
10 clippy::mod_module_files,
11 missing_docs,
12 missing_debug_implementations,
13 missing_copy_implementations,
14 rust_2018_idioms,
15 trivial_casts,
16 trivial_numeric_casts,
17 unused_qualifications
18)]
19#![cfg_attr(not(test), warn(clippy::unwrap_used))]
20
21//! ## Usage
22//!
23//! The core types of `crypto-bigint` are as follows:
24//!
25//! - [`Uint`]: stack-allocated big integer type, const generic around a number of [`Limb`]s.
26//! Type aliases are provided for various sizes, e.g. [`U128`], [`U384`], [`U256`], [`U2048`],
27//! [`U3072`], [`U4096`].
28//! - [`BoxedUint`]: heap-allocated big integer type. Requires the `alloc` crate feature is enabled.
29//!
30//! Big integer types in this crate use a 32-bit or 64-bit saturated representation, depending on
31//! the underlying CPU's pointer width.
32//!
33//! The following types for modular arithmetic are available under the [`modular`] submodule:
34//!
35//! - [`modular::ConstMontyForm`]: stack-allocated type-safe modular arithmetic using Montgomery
36//! form suitable for cases where the modulus is known at compile-time.
37//! - [`modular::MontyForm`]: stack-allocated modular arithmetic using Montgomery form for cases
38//! where the modulus is only known at runtime.
39//! - [`modular::BoxedMontyForm`]: heap-allocated modular arithmetic using Montgomery form.
40//! Requires the `alloc` crate feature is enabled.
41//!
42//! ### `const fn` usage
43//!
44//! The [`Uint`] type provides a number of `const fn` inherent methods which
45//! can be used for initializing and performing arithmetic on big integers in
46//! const contexts:
47//!
48//! ```
49//! use crypto_bigint::U256;
50//!
51//! // Parse a constant from a big endian hexadecimal string.
52//! pub const MODULUS: U256 =
53//! U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
54//!
55//! // Compute `MODULUS` shifted right by 1 at compile time
56//! pub const MODULUS_SHR1: U256 = MODULUS.shr(1);
57//! ```
58//!
59//! ### Trait-based usage
60//!
61//! The [`Uint`] type itself does not implement the standard arithmetic traits
62//! such as [`Add`], [`Sub`], [`Mul`], and [`Div`].
63//!
64//! To use these traits you must first pick a wrapper type which determines
65//! overflow behavior: [`Wrapping`] or [`Checked`].
66//!
67//! #### Wrapping arithmetic
68//!
69//! ```
70//! use crypto_bigint::{U256, Wrapping};
71//!
72//! let a = Wrapping(U256::MAX);
73//! let b = Wrapping(U256::ONE);
74//! let c = a + b;
75//!
76//! // `MAX` + 1 wraps back around to zero
77//! assert_eq!(c.0, U256::ZERO);
78//! ```
79//!
80//! #### Checked arithmetic
81//!
82//! ```
83//! use crypto_bigint::{U256, Checked};
84//!
85//! let a = Checked::new(U256::ONE);
86//! let b = Checked::new(U256::from(2u8));
87//! let c = a + b;
88//! assert_eq!(c.0.unwrap(), U256::from(3u8))
89//! ```
90//!
91//! ### Modular arithmetic
92//!
93//! See the [`modular`] module for types which implement Montgomery form modular arithmetic.
94//!
95//! This library also has support for performing modular arithmetic on integers in the form of the
96//! [`AddMod`], [`SubMod`], [`NegMod`], and [`MulMod`] traits, as well as the support for the
97//! [`Rem`] trait when used with a [`NonZero`] operand.
98//!
99//! ```
100//! use crypto_bigint::{AddMod, NonZero, U256};
101//!
102//! // mod 3
103//! let modulus = NonZero::new(U256::from(3u8)).expect("non-zero");
104//!
105//! // 1 + 1 mod 3 = 2
106//! let a = U256::ONE.add_mod(&U256::ONE, &modulus);
107//! assert_eq!(a, U256::from(2u8));
108//!
109//! // 2 + 1 mod 3 = 0
110//! let b = a.add_mod(&U256::ONE, &modulus);
111//! assert_eq!(b, U256::ZERO);
112//! ```
113//!
114//! ### Random number generation
115//!
116//! When the `rand_core` feature of this crate are enabled, it's possible to generate random numbers
117//! using any RNG by using the [`Random`] trait:
118//!
119//! ```
120//! # #[cfg(feature = "rand")]
121//! # {
122//! # use rand_chacha::ChaCha8Rng;
123//! # use rand_core::SeedableRng;
124//! # fn rng() -> ChaCha8Rng {
125//! # ChaCha8Rng::from_seed(*b"01234567890123456789012345678901")
126//! # }
127//! use crypto_bigint::{Random, U256};
128//!
129//! let n = U256::random(&mut rng());
130//! # }
131//! ```
132//!
133//! #### Modular random number generation
134//!
135//! The [`RandomMod`] trait supports generating random numbers with a uniform
136//! distribution around a given [`NonZero`] modulus.
137//!
138//! ```
139//! # #[cfg(feature = "rand")]
140//! # {
141//! # use rand_chacha::ChaCha8Rng;
142//! # use rand_core::SeedableRng;
143//! # fn rng() -> ChaCha8Rng {
144//! # ChaCha8Rng::from_seed(*b"01234567890123456789012345678901")
145//! # }
146//! use crypto_bigint::{NonZero, RandomMod, U256};
147//!
148//! let modulus = NonZero::new(U256::from(3u8)).unwrap();
149//! let n = U256::random_mod(&mut rng(), &modulus);
150//! # }
151//! ```
152//!
153//! [`Add`]: core::ops::Add
154//! [`Div`]: core::ops::Div
155//! [`Mul`]: core::ops::Mul
156//! [`Rem`]: core::ops::Rem
157//! [`Sub`]: core::ops::Sub
158//!
159//! ## `crypto-primes` crate
160//!
161//! This crate contains no prime number related functionality (e.g. random prime generation). Such
162//! functionality can be found in the companion [`crypto-primes`](https://docs.rs/crypto-primes)
163//! crate.
164
165#[cfg(feature = "alloc")]
166#[allow(unused_imports)]
167#[macro_use]
168extern crate alloc;
169
170#[cfg(feature = "rand_core")]
171pub use rand_core;
172#[cfg(feature = "rlp")]
173pub use rlp;
174pub use subtle;
175#[cfg(feature = "zeroize")]
176pub use zeroize;
177
178#[cfg(feature = "hybrid-array")]
179pub use {
180 crate::array::{ArrayDecoding, ArrayEncoding, ByteArray},
181 hybrid_array::{self, typenum::consts},
182};
183
184#[cfg(feature = "alloc")]
185pub use crate::uint::boxed::BoxedUint;
186pub use crate::{
187 checked::Checked,
188 const_choice::{ConstChoice, ConstCtOption},
189 int::types::*,
190 int::*,
191 limb::{Limb, WideWord, Word},
192 non_zero::*,
193 odd::*,
194 traits::*,
195 uint::{div_limb::Reciprocal, *},
196 wrapping::Wrapping,
197};
198
199#[macro_use]
200mod macros;
201
202pub mod modular;
203
204#[cfg(feature = "hybrid-array")]
205mod array;
206mod checked;
207mod const_choice;
208mod int;
209mod limb;
210mod non_zero;
211mod odd;
212mod primitives;
213mod traits;
214mod uint;
215mod wrapping;
216
217/// Import prelude for this crate: includes important traits.
218pub mod prelude {
219 #[cfg(feature = "hybrid-array")]
220 pub use crate::array::{ArrayDecoding, ArrayEncoding};
221 pub use crate::traits::*;
222}