/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 | | } |