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