]> git.proxmox.com Git - rustc.git/blame - vendor/crypto-bigint/src/uint/from.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / vendor / crypto-bigint / src / uint / from.rs
CommitLineData
49aad941 1//! `From`-like conversions for [`Uint`].
0a29b90c 2
49aad941 3use crate::{Limb, Uint, WideWord, Word, U128, U64};
0a29b90c 4
49aad941
FG
5impl<const LIMBS: usize> Uint<LIMBS> {
6 /// Create a [`Uint`] from a `u8` (const-friendly)
0a29b90c
FG
7 // TODO(tarcieri): replace with `const impl From<u8>` when stable
8 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
49aad941 15 /// Create a [`Uint`] from a `u16` (const-friendly)
0a29b90c
FG
16 // TODO(tarcieri): replace with `const impl From<u16>` when stable
17 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
49aad941 24 /// Create a [`Uint`] from a `u32` (const-friendly)
0a29b90c
FG
25 // TODO(tarcieri): replace with `const impl From<u32>` when stable
26 #[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
49aad941 34 /// Create a [`Uint`] from a `u64` (const-friendly)
0a29b90c
FG
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
49aad941 45 /// Create a [`Uint`] from a `u64` (const-friendly)
0a29b90c
FG
46 // TODO(tarcieri): replace with `const impl From<u64>` when stable
47 #[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
49aad941 55 /// Create a [`Uint`] from a `u128` (const-friendly)
0a29b90c
FG
56 // TODO(tarcieri): replace with `const impl From<u128>` when stable
57 pub const fn from_u128(n: u128) -> Self {
58 assert!(
49aad941 59 LIMBS >= (128 / Limb::BITS),
0a29b90c
FG
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
49aad941 83 /// Create a [`Uint`] from a `Word` (const-friendly)
0a29b90c
FG
84 // TODO(tarcieri): replace with `const impl From<Word>` when stable
85 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
49aad941 92 /// Create a [`Uint`] from a `WideWord` (const-friendly)
0a29b90c
FG
93 // TODO(tarcieri): replace with `const impl From<WideWord>` when stable
94 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;
49aad941 98 limbs[1].0 = (n >> Limb::BITS) as Word;
0a29b90c
FG
99 Self { limbs }
100 }
101}
102
49aad941 103impl<const LIMBS: usize> From<u8> for Uint<LIMBS> {
0a29b90c
FG
104 fn from(n: u8) -> Self {
105 // TODO(tarcieri): const where clause when possible
106 debug_assert!(LIMBS > 0, "limbs must be non-zero");
107 Self::from_u8(n)
108 }
109}
110
49aad941 111impl<const LIMBS: usize> From<u16> for Uint<LIMBS> {
0a29b90c
FG
112 fn from(n: u16) -> Self {
113 // TODO(tarcieri): const where clause when possible
114 debug_assert!(LIMBS > 0, "limbs must be non-zero");
115 Self::from_u16(n)
116 }
117}
118
49aad941 119impl<const LIMBS: usize> From<u32> for Uint<LIMBS> {
0a29b90c
FG
120 fn from(n: u32) -> Self {
121 // TODO(tarcieri): const where clause when possible
122 debug_assert!(LIMBS > 0, "limbs must be non-zero");
123 Self::from_u32(n)
124 }
125}
126
49aad941 127impl<const LIMBS: usize> From<u64> for Uint<LIMBS> {
0a29b90c
FG
128 fn from(n: u64) -> Self {
129 // TODO(tarcieri): const where clause when possible
49aad941 130 debug_assert!(LIMBS >= (64 / Limb::BITS), "not enough limbs");
0a29b90c
FG
131 Self::from_u64(n)
132 }
133}
134
49aad941 135impl<const LIMBS: usize> From<u128> for Uint<LIMBS> {
0a29b90c
FG
136 fn from(n: u128) -> Self {
137 // TODO(tarcieri): const where clause when possible
49aad941 138 debug_assert!(LIMBS >= (128 / Limb::BITS), "not enough limbs");
0a29b90c
FG
139 Self::from_u128(n)
140 }
141}
142
143#[cfg(target_pointer_width = "32")]
0a29b90c
FG
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")]
0a29b90c
FG
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 (hi, lo) = n.split();
160 (u64::from(hi) as u128) << 64 | (u64::from(lo) as u128)
161 }
162}
163
49aad941 164impl<const LIMBS: usize> From<[Word; LIMBS]> for Uint<LIMBS> {
0a29b90c
FG
165 fn from(arr: [Word; LIMBS]) -> Self {
166 Self::from_words(arr)
167 }
168}
169
49aad941
FG
170impl<const LIMBS: usize> From<Uint<LIMBS>> for [Word; LIMBS] {
171 fn from(n: Uint<LIMBS>) -> [Word; LIMBS] {
0a29b90c
FG
172 *n.as_ref()
173 }
174}
175
49aad941 176impl<const LIMBS: usize> From<[Limb; LIMBS]> for Uint<LIMBS> {
0a29b90c
FG
177 fn from(limbs: [Limb; LIMBS]) -> Self {
178 Self { limbs }
179 }
180}
181
49aad941
FG
182impl<const LIMBS: usize> From<Uint<LIMBS>> for [Limb; LIMBS] {
183 fn from(n: Uint<LIMBS>) -> [Limb; LIMBS] {
0a29b90c
FG
184 n.limbs
185 }
186}
187
49aad941 188impl<const LIMBS: usize> From<Limb> for Uint<LIMBS> {
0a29b90c
FG
189 fn from(limb: Limb) -> Self {
190 limb.0.into()
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use crate::{Limb, Word, U128};
197
198 #[cfg(target_pointer_width = "32")]
49aad941 199 use crate::U64 as UintEx;
0a29b90c
FG
200
201 #[cfg(target_pointer_width = "64")]
49aad941 202 use crate::U128 as UintEx;
0a29b90c
FG
203
204 #[test]
205 fn from_u8() {
49aad941
FG
206 let n = UintEx::from(42u8);
207 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
0a29b90c
FG
208 }
209
210 #[test]
211 fn from_u16() {
49aad941
FG
212 let n = UintEx::from(42u16);
213 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
0a29b90c
FG
214 }
215
216 #[test]
217 fn from_u64() {
49aad941
FG
218 let n = UintEx::from(42u64);
219 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
0a29b90c
FG
220 }
221
222 #[test]
223 fn from_u128() {
224 let n = U128::from(42u128);
49aad941 225 assert_eq!(&n.as_limbs()[..2], &[Limb(42), Limb(0)]);
0a29b90c
FG
226 assert_eq!(u128::from(n), 42u128);
227 }
228
229 #[test]
230 fn array_round_trip() {
231 let arr1 = [1, 2];
49aad941 232 let n = UintEx::from(arr1);
0a29b90c
FG
233 let arr2: [Word; 2] = n.into();
234 assert_eq!(arr1, arr2);
235 }
236}