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 clippy::unwrap_used,
12 missing_docs,
13 missing_debug_implementations,
14 missing_copy_implementations,
15 rust_2018_idioms,
16 trivial_casts,
17 trivial_numeric_casts,
18 unused_qualifications
19)]
20
21//! ## Usage
22//!
23//! This crate defines a [`Uint`] type which is const generic around an inner
24//! [`Limb`] array, where a [`Limb`] is a newtype for a word-sized integer.
25//! Thus large integers are represented as arrays of smaller integers which
26//! are sized appropriately for the CPU, giving us some assurances of how
27//! arithmetic operations over those smaller integers will behave.
28//!
29//! To obtain appropriately sized integers regardless of what a given CPU's
30//! word size happens to be, a number of portable type aliases are provided for
31//! integer sizes commonly used in cryptography, for example:
32//! [`U128`], [`U384`], [`U256`], [`U2048`], [`U3072`], [`U4096`].
33//!
34//! ### `const fn` usage
35//!
36//! The [`Uint`] type provides a number of `const fn` inherent methods which
37//! can be used for initializing and performing arithmetic on big integers in
38//! const contexts:
39//!
40//! ```
41//! use crypto_bigint::U256;
42//!
43//! // Parse a constant from a big endian hexadecimal string.
44//! pub const MODULUS: U256 =
45//! U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
46//!
47//! // Compute `MODULUS` shifted right by 1 at compile time
48//! pub const MODULUS_SHR1: U256 = MODULUS.shr_vartime(1);
49//! ```
50//!
51//! Note that large constant computations may accidentally trigger a the `const_eval_limit` of the compiler.
52//! The current way to deal with this problem is to either simplify this computation,
53//! or increase the compiler's limit (currently a nightly feature).
54//! One can completely remove the compiler's limit using:
55//! ```ignore
56//! #![feature(const_eval_limit)]
57//! #![const_eval_limit = "0"]
58//! ```
59//!
60//! ### Trait-based usage
61//!
62//! The [`Uint`] type itself does not implement the standard arithmetic traits
63//! such as [`Add`], [`Sub`], [`Mul`], and [`Div`].
64//!
65//! To use these traits you must first pick a wrapper type which determines
66//! overflow behavior: [`Wrapping`] or [`Checked`].
67//!
68//! #### Wrapping arithmetic
69//!
70//! ```
71//! use crypto_bigint::{U256, Wrapping};
72//!
73//! let a = Wrapping(U256::MAX);
74//! let b = Wrapping(U256::ONE);
75//! let c = a + b;
76//!
77//! // `MAX` + 1 wraps back around to zero
78//! assert_eq!(c.0, U256::ZERO);
79//! ```
80//!
81//! #### Checked arithmetic
82//!
83//! ```
84//! use crypto_bigint::{U256, Checked};
85//!
86//! let a = Checked::new(U256::ONE);
87//! let b = Checked::new(U256::from(2u8));
88//! let c = a + b;
89//! assert_eq!(c.0.unwrap(), U256::from(3u8))
90//! ```
91//!
92//! ### Modular arithmetic
93//!
94//! This library has initial support for modular arithmetic in the form of the
95//! [`AddMod`], [`SubMod`], [`NegMod`], and [`MulMod`] traits, as well as the
96//! support for the [`Rem`] trait when used with a [`NonZero`] operand.
97//!
98//! ```
99//! use crypto_bigint::{AddMod, U256};
100//!
101//! // mod 3
102//! let modulus = U256::from(3u8);
103//!
104//! // 1 + 1 mod 3 = 2
105//! let a = U256::ONE.add_mod(&U256::ONE, &modulus);
106//! assert_eq!(a, U256::from(2u8));
107//!
108//! // 2 + 1 mod 3 = 0
109//! let b = a.add_mod(&U256::ONE, &modulus);
110//! assert_eq!(b, U256::ZERO);
111//! ```
112//!
113//! It also supports modular arithmetic over constant moduli using `Residue`,
114//! and over moduli set at runtime using `DynResidue`.
115//! That includes modular exponentiation and multiplicative inverses.
116//! These features are described in the [`modular`] module.
117//!
118//! ### Random number generation
119//!
120//! When the `rand_core` or `rand` features of this crate are enabled, it's
121//! possible to generate random numbers using any CSRNG by using the
122//! [`Random`] trait:
123//!
124//! ```
125//! # #[cfg(feature = "rand")]
126//! # {
127//! use crypto_bigint::{Random, U256, rand_core::OsRng};
128//!
129//! let n = U256::random(&mut OsRng);
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 crypto_bigint::{NonZero, RandomMod, U256, rand_core::OsRng};
142//!
143//! let modulus = NonZero::new(U256::from(3u8)).unwrap();
144//! let n = U256::random_mod(&mut OsRng, &modulus);
145//! # }
146//! ```
147//!
148//! [`Add`]: core::ops::Add
149//! [`Div`]: core::ops::Div
150//! [`Mul`]: core::ops::Mul
151//! [`Rem`]: core::ops::Rem
152//! [`Sub`]: core::ops::Sub
153
154#[cfg(feature = "alloc")]
155#[allow(unused_imports)]
156#[macro_use]
157extern crate alloc;
158
159#[macro_use]
160mod macros;
161
162#[cfg(feature = "generic-array")]
163mod array;
164#[cfg(feature = "alloc")]
165mod boxed;
166mod checked;
167mod ct_choice;
168mod limb;
169mod non_zero;
170mod traits;
171mod uint;
172mod wrapping;
173
174pub use crate::{
175 checked::Checked,
176 ct_choice::CtChoice,
177 limb::{Limb, WideWord, Word},
178 non_zero::NonZero,
179 traits::*,
180 uint::div_limb::Reciprocal,
181 uint::*,
182 wrapping::Wrapping,
183};
184pub use subtle;
185
186#[cfg(feature = "alloc")]
187pub use crate::boxed::uint::BoxedUint;
188
189#[cfg(feature = "generic-array")]
190pub use {
191 crate::array::{ArrayDecoding, ArrayEncoding, ByteArray},
192 generic_array::{self, typenum::consts},
193};
194
195#[cfg(feature = "rand_core")]
196pub use rand_core;
197
198#[cfg(feature = "rlp")]
199pub use rlp;
200
201#[cfg(feature = "zeroize")]
202pub use zeroize;
203
204/// Import prelude for this crate: includes important traits.
205pub mod prelude {
206 pub use crate::traits::*;
207
208 #[cfg(feature = "generic-array")]
209 pub use crate::array::{ArrayDecoding, ArrayEncoding};
210}
211
212#[cfg(sidefuzz)]
213#[no_mangle]
214pub extern "C" fn fuzz() {
215 let input = sidefuzz::fetch_input(32); // 32 bytes of of fuzzing input as a &[u8]
216 sidefuzz::black_box(my_hopefully_constant_fn(input));
217}