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