Coverage Report

Created: 2025-07-23 06:36

/rust/registry/src/index.crates.io-6f17d22bba15001f/crypto-bigint-0.5.5/src/uint/from.rs
Line
Count
Source (jump to first uncovered line)
1
//! `From`-like conversions for [`Uint`].
2
3
use crate::{ConcatMixed, Limb, Uint, WideWord, Word, U128, U64};
4
5
impl<const LIMBS: usize> Uint<LIMBS> {
6
    /// Create a [`Uint`] from a `u8` (const-friendly)
7
    // TODO(tarcieri): replace with `const impl From<u8>` when stable
8
0
    pub const fn from_u8(n: u8) -> Self {
9
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
10
0
        let mut limbs = [Limb::ZERO; LIMBS];
11
0
        limbs[0].0 = n as Word;
12
0
        Self { limbs }
13
0
    }
14
15
    /// Create a [`Uint`] from a `u16` (const-friendly)
16
    // TODO(tarcieri): replace with `const impl From<u16>` when stable
17
0
    pub const fn from_u16(n: u16) -> Self {
18
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
19
0
        let mut limbs = [Limb::ZERO; LIMBS];
20
0
        limbs[0].0 = n as Word;
21
0
        Self { limbs }
22
0
    }
23
24
    /// Create a [`Uint`] from a `u32` (const-friendly)
25
    // TODO(tarcieri): replace with `const impl From<u32>` when stable
26
    #[allow(trivial_numeric_casts)]
27
0
    pub const fn from_u32(n: u32) -> Self {
28
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
29
0
        let mut limbs = [Limb::ZERO; LIMBS];
30
0
        limbs[0].0 = n as Word;
31
0
        Self { limbs }
32
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<4>>::from_u32
Unexecuted instantiation: <crypto_bigint::uint::Uint<_>>::from_u32
33
34
    /// Create a [`Uint`] from a `u64` (const-friendly)
35
    // TODO(tarcieri): replace with `const impl From<u64>` when stable
36
    #[cfg(target_pointer_width = "32")]
37
    pub const fn from_u64(n: u64) -> Self {
38
        assert!(LIMBS >= 2, "number of limbs must be two or greater");
39
        let mut limbs = [Limb::ZERO; LIMBS];
40
        limbs[0].0 = (n & 0xFFFFFFFF) as u32;
41
        limbs[1].0 = (n >> 32) as u32;
42
        Self { limbs }
43
    }
44
45
    /// Create a [`Uint`] from a `u64` (const-friendly)
46
    // TODO(tarcieri): replace with `const impl From<u64>` when stable
47
    #[cfg(target_pointer_width = "64")]
48
0
    pub const fn from_u64(n: u64) -> Self {
49
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
50
0
        let mut limbs = [Limb::ZERO; LIMBS];
51
0
        limbs[0].0 = n;
52
0
        Self { limbs }
53
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<1>>::from_u64
Unexecuted instantiation: <crypto_bigint::uint::Uint<4>>::from_u64
Unexecuted instantiation: <crypto_bigint::uint::Uint<_>>::from_u64
54
55
    /// Create a [`Uint`] from a `u128` (const-friendly)
56
    // TODO(tarcieri): replace with `const impl From<u128>` when stable
57
0
    pub const fn from_u128(n: u128) -> Self {
58
0
        assert!(
59
0
            LIMBS >= (128 / Limb::BITS),
60
0
            "number of limbs must be greater than zero"
61
        );
62
63
0
        let lo = U64::from_u64((n & 0xffff_ffff_ffff_ffff) as u64);
64
0
        let hi = U64::from_u64((n >> 64) as u64);
65
0
66
0
        let mut limbs = [Limb::ZERO; LIMBS];
67
0
68
0
        let mut i = 0;
69
0
        while i < lo.limbs.len() {
70
0
            limbs[i] = lo.limbs[i];
71
0
            i += 1;
72
0
        }
73
74
0
        let mut j = 0;
75
0
        while j < hi.limbs.len() {
76
0
            limbs[i + j] = hi.limbs[j];
77
0
            j += 1;
78
0
        }
79
80
0
        Self { limbs }
81
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<4>>::from_u128
Unexecuted instantiation: <crypto_bigint::uint::Uint<_>>::from_u128
82
83
    /// Create a [`Uint`] from a `Word` (const-friendly)
84
    // TODO(tarcieri): replace with `const impl From<Word>` when stable
85
0
    pub const fn from_word(n: Word) -> Self {
86
0
        assert!(LIMBS >= 1, "number of limbs must be greater than zero");
87
0
        let mut limbs = [Limb::ZERO; LIMBS];
88
0
        limbs[0].0 = n;
89
0
        Self { limbs }
90
0
    }
91
92
    /// Create a [`Uint`] from a `WideWord` (const-friendly)
93
    // TODO(tarcieri): replace with `const impl From<WideWord>` when stable
94
0
    pub const fn from_wide_word(n: WideWord) -> Self {
95
0
        assert!(LIMBS >= 2, "number of limbs must be two or greater");
96
0
        let mut limbs = [Limb::ZERO; LIMBS];
97
0
        limbs[0].0 = n as Word;
98
0
        limbs[1].0 = (n >> Limb::BITS) as Word;
99
0
        Self { limbs }
100
0
    }
101
}
102
103
impl<const LIMBS: usize> From<u8> for Uint<LIMBS> {
104
0
    fn from(n: u8) -> Self {
105
0
        // TODO(tarcieri): const where clause when possible
106
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
107
0
        Self::from_u8(n)
108
0
    }
109
}
110
111
impl<const LIMBS: usize> From<u16> for Uint<LIMBS> {
112
0
    fn from(n: u16) -> Self {
113
0
        // TODO(tarcieri): const where clause when possible
114
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
115
0
        Self::from_u16(n)
116
0
    }
117
}
118
119
impl<const LIMBS: usize> From<u32> for Uint<LIMBS> {
120
0
    fn from(n: u32) -> Self {
121
0
        // TODO(tarcieri): const where clause when possible
122
0
        debug_assert!(LIMBS > 0, "limbs must be non-zero");
123
0
        Self::from_u32(n)
124
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<4> as core::convert::From<u32>>::from
Unexecuted instantiation: <crypto_bigint::uint::Uint<_> as core::convert::From<u32>>::from
125
}
126
127
impl<const LIMBS: usize> From<u64> for Uint<LIMBS> {
128
0
    fn from(n: u64) -> Self {
129
0
        // TODO(tarcieri): const where clause when possible
130
0
        debug_assert!(LIMBS >= (64 / Limb::BITS), "not enough limbs");
131
0
        Self::from_u64(n)
132
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<4> as core::convert::From<u64>>::from
Unexecuted instantiation: <crypto_bigint::uint::Uint<_> as core::convert::From<u64>>::from
133
}
134
135
impl<const LIMBS: usize> From<u128> for Uint<LIMBS> {
136
0
    fn from(n: u128) -> Self {
137
0
        // TODO(tarcieri): const where clause when possible
138
0
        debug_assert!(LIMBS >= (128 / Limb::BITS), "not enough limbs");
139
0
        Self::from_u128(n)
140
0
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<4> as core::convert::From<u128>>::from
Unexecuted instantiation: <crypto_bigint::uint::Uint<_> as core::convert::From<u128>>::from
141
}
142
143
#[cfg(target_pointer_width = "32")]
144
impl From<U64> for u64 {
145
    fn from(n: U64) -> u64 {
146
        (n.limbs[0].0 as u64) | ((n.limbs[1].0 as u64) << 32)
147
    }
148
}
149
150
#[cfg(target_pointer_width = "64")]
151
impl From<U64> for u64 {
152
0
    fn from(n: U64) -> u64 {
153
0
        n.limbs[0].into()
154
0
    }
155
}
156
157
impl From<U128> for u128 {
158
0
    fn from(n: U128) -> u128 {
159
0
        let mut i = U128::LIMBS - 1;
160
0
        let mut res = n.limbs[i].0 as u128;
161
0
        while i > 0 {
162
0
            i -= 1;
163
0
            res = (res << Limb::BITS) | (n.limbs[i].0 as u128);
164
0
        }
165
0
        res
166
0
    }
167
}
168
169
impl<const LIMBS: usize> From<[Word; LIMBS]> for Uint<LIMBS> {
170
68.2M
    fn from(arr: [Word; LIMBS]) -> Self {
171
68.2M
        Self::from_words(arr)
172
68.2M
    }
<crypto_bigint::uint::Uint<4> as core::convert::From<[u64; 4]>>::from
Line
Count
Source
170
68.2M
    fn from(arr: [Word; LIMBS]) -> Self {
171
68.2M
        Self::from_words(arr)
172
68.2M
    }
Unexecuted instantiation: <crypto_bigint::uint::Uint<_> as core::convert::From<[u64; _]>>::from
173
}
174
175
impl<const LIMBS: usize> From<Uint<LIMBS>> for [Word; LIMBS] {
176
0
    fn from(n: Uint<LIMBS>) -> [Word; LIMBS] {
177
0
        *n.as_ref()
178
0
    }
179
}
180
181
impl<const LIMBS: usize> From<[Limb; LIMBS]> for Uint<LIMBS> {
182
0
    fn from(limbs: [Limb; LIMBS]) -> Self {
183
0
        Self { limbs }
184
0
    }
185
}
186
187
impl<const LIMBS: usize> From<Uint<LIMBS>> for [Limb; LIMBS] {
188
0
    fn from(n: Uint<LIMBS>) -> [Limb; LIMBS] {
189
0
        n.limbs
190
0
    }
191
}
192
193
impl<const LIMBS: usize> From<Limb> for Uint<LIMBS> {
194
0
    fn from(limb: Limb) -> Self {
195
0
        limb.0.into()
196
0
    }
197
}
198
199
impl<const L: usize, const H: usize, const LIMBS: usize> From<(Uint<L>, Uint<H>)> for Uint<LIMBS>
200
where
201
    Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
202
{
203
0
    fn from(nums: (Uint<L>, Uint<H>)) -> Uint<LIMBS> {
204
0
        nums.1.concat_mixed(&nums.0)
205
0
    }
206
}
207
208
impl<const L: usize, const H: usize, const LIMBS: usize> From<&(Uint<L>, Uint<H>)> for Uint<LIMBS>
209
where
210
    Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
211
{
212
0
    fn from(nums: &(Uint<L>, Uint<H>)) -> Uint<LIMBS> {
213
0
        nums.1.concat_mixed(&nums.0)
214
0
    }
215
}
216
217
impl<const L: usize, const H: usize, const LIMBS: usize> From<Uint<LIMBS>> for (Uint<L>, Uint<H>) {
218
0
    fn from(num: Uint<LIMBS>) -> (Uint<L>, Uint<H>) {
219
0
        crate::uint::split::split_mixed(&num)
220
0
    }
221
}
222
223
impl<const LIMBS: usize, const LIMBS2: usize> From<&Uint<LIMBS>> for Uint<LIMBS2> {
224
0
    fn from(num: &Uint<LIMBS>) -> Uint<LIMBS2> {
225
0
        num.resize()
226
0
    }
227
}
228
229
#[cfg(test)]
230
mod tests {
231
    use crate::{Limb, Word, U128};
232
233
    #[cfg(target_pointer_width = "32")]
234
    use crate::U64 as UintEx;
235
236
    #[cfg(target_pointer_width = "64")]
237
    use crate::U128 as UintEx;
238
239
    #[test]
240
    fn from_u8() {
241
        let n = UintEx::from(42u8);
242
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
243
    }
244
245
    #[test]
246
    fn from_u16() {
247
        let n = UintEx::from(42u16);
248
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
249
    }
250
251
    #[test]
252
    fn from_u64() {
253
        let n = UintEx::from(42u64);
254
        assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
255
    }
256
257
    #[test]
258
    fn from_u128() {
259
        let n = U128::from(42u128);
260
        assert_eq!(&n.as_limbs()[..2], &[Limb(42), Limb(0)]);
261
        assert_eq!(u128::from(n), 42u128);
262
    }
263
264
    #[test]
265
    fn array_round_trip() {
266
        let arr1 = [1, 2];
267
        let n = UintEx::from(arr1);
268
        let arr2: [Word; 2] = n.into();
269
        assert_eq!(arr1, arr2);
270
    }
271
}