Coverage Report

Created: 2026-08-14 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-bigint-0.5.5/src/limb.rs
Line
Count
Source
1
//! Big integers are represented as an array of smaller CPU word-size integers
2
//! called "limbs".
3
4
mod add;
5
mod bit_and;
6
mod bit_not;
7
mod bit_or;
8
mod bit_xor;
9
mod bits;
10
mod cmp;
11
mod encoding;
12
mod from;
13
mod mul;
14
mod neg;
15
mod shl;
16
mod shr;
17
mod sub;
18
19
#[cfg(feature = "rand_core")]
20
mod rand;
21
22
use crate::{Bounded, Zero};
23
use core::fmt;
24
use subtle::{Choice, ConditionallySelectable};
25
26
#[cfg(feature = "serde")]
27
use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
28
29
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
30
compile_error!("this crate builds on 32-bit and 64-bit platforms only");
31
32
//
33
// 32-bit definitions
34
//
35
36
/// Inner integer type that the [`Limb`] newtype wraps.
37
#[cfg(target_pointer_width = "32")]
38
pub type Word = u32;
39
40
/// Unsigned wide integer type: double the width of [`Word`].
41
#[cfg(target_pointer_width = "32")]
42
pub type WideWord = u64;
43
44
//
45
// 64-bit definitions
46
//
47
48
/// Unsigned integer type that the [`Limb`] newtype wraps.
49
#[cfg(target_pointer_width = "64")]
50
pub type Word = u64;
51
52
/// Wide integer type: double the width of [`Word`].
53
#[cfg(target_pointer_width = "64")]
54
pub type WideWord = u128;
55
56
/// Highest bit in a [`Limb`].
57
pub(crate) const HI_BIT: usize = Limb::BITS - 1;
58
59
/// Big integers are represented as an array of smaller CPU word-size integers
60
/// called "limbs".
61
// Our PartialEq impl only differs from the default one by being constant-time, so this is safe
62
#[allow(clippy::derived_hash_with_manual_eq)]
63
#[derive(Copy, Clone, Default, Hash)]
64
#[repr(transparent)]
65
pub struct Limb(pub Word);
66
67
impl Limb {
68
    /// The value `0`.
69
    pub const ZERO: Self = Limb(0);
70
71
    /// The value `1`.
72
    pub const ONE: Self = Limb(1);
73
74
    /// Maximum value this [`Limb`] can express.
75
    pub const MAX: Self = Limb(Word::MAX);
76
77
    // 32-bit
78
79
    /// Size of the inner integer in bits.
80
    #[cfg(target_pointer_width = "32")]
81
    pub const BITS: usize = 32;
82
    /// Size of the inner integer in bytes.
83
    #[cfg(target_pointer_width = "32")]
84
    pub const BYTES: usize = 4;
85
86
    // 64-bit
87
88
    /// Size of the inner integer in bits.
89
    #[cfg(target_pointer_width = "64")]
90
    pub const BITS: usize = 64;
91
    /// Size of the inner integer in bytes.
92
    #[cfg(target_pointer_width = "64")]
93
    pub const BYTES: usize = 8;
94
}
95
96
impl Bounded for Limb {
97
    const BITS: usize = Self::BITS;
98
    const BYTES: usize = Self::BYTES;
99
}
100
101
impl ConditionallySelectable for Limb {
102
    #[inline]
103
95.4M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
104
95.4M
        Self(Word::conditional_select(&a.0, &b.0, choice))
105
95.4M
    }
<crypto_bigint::limb::Limb as subtle::ConditionallySelectable>::conditional_select
Line
Count
Source
103
95.4M
    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
104
95.4M
        Self(Word::conditional_select(&a.0, &b.0, choice))
105
95.4M
    }
Unexecuted instantiation: <crypto_bigint::limb::Limb as subtle::ConditionallySelectable>::conditional_select
106
}
107
108
impl Zero for Limb {
109
    const ZERO: Self = Self::ZERO;
110
}
111
112
impl fmt::Debug for Limb {
113
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114
0
        write!(f, "Limb(0x{self:X})")
115
0
    }
116
}
117
118
impl fmt::Display for Limb {
119
    #[inline]
120
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121
0
        fmt::UpperHex::fmt(self, f)
122
0
    }
123
}
124
125
impl fmt::LowerHex for Limb {
126
    #[inline]
127
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128
0
        write!(f, "{:0width$x}", &self.0, width = Self::BYTES * 2)
129
0
    }
130
}
131
132
impl fmt::UpperHex for Limb {
133
    #[inline]
134
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135
0
        write!(f, "{:0width$X}", &self.0, width = Self::BYTES * 2)
136
0
    }
Unexecuted instantiation: <crypto_bigint::limb::Limb as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <crypto_bigint::limb::Limb as core::fmt::UpperHex>::fmt
137
}
138
139
#[cfg(feature = "serde")]
140
impl<'de> Deserialize<'de> for Limb {
141
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
142
    where
143
        D: Deserializer<'de>,
144
    {
145
        Ok(Self(Word::deserialize(deserializer)?))
146
    }
147
}
148
149
#[cfg(feature = "serde")]
150
impl Serialize for Limb {
151
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
152
    where
153
        S: Serializer,
154
    {
155
        self.0.serialize(serializer)
156
    }
157
}
158
159
#[cfg(feature = "zeroize")]
160
impl zeroize::DefaultIsZeroes for Limb {}
161
162
#[cfg(test)]
163
mod tests {
164
    #[cfg(feature = "alloc")]
165
    use {super::Limb, alloc::format};
166
167
    #[cfg(feature = "alloc")]
168
    #[test]
169
    fn debug() {
170
        #[cfg(target_pointer_width = "32")]
171
        assert_eq!(format!("{:?}", Limb(42)), "Limb(0x0000002A)");
172
173
        #[cfg(target_pointer_width = "64")]
174
        assert_eq!(format!("{:?}", Limb(42)), "Limb(0x000000000000002A)");
175
    }
176
}