Skip to content

Commit 6ee7e8d

Browse files
authored
Add transformation utility functions between biguint and words. (#14)
Add biguint <-> words
1 parent a1050f9 commit 6ee7e8d

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

crates/curves/src/utils.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,65 @@ cfg_if::cfg_if! {
4646
}
4747
}
4848
}
49+
50+
#[inline]
51+
pub fn biguint_from_words(words: &[u32]) -> BigUint {
52+
let mut bytes = Vec::with_capacity(words.len() * 4);
53+
for word in words {
54+
bytes.extend_from_slice(&word.to_le_bytes());
55+
}
56+
BigUint::from_bytes_le(&bytes)
57+
}
58+
59+
#[inline]
60+
pub fn biguint_to_words(integer: &BigUint, num_words: usize) -> Vec<u32> {
61+
let mut bytes = integer.to_bytes_le();
62+
bytes.resize(num_words * 4, 0u8);
63+
let mut words = Vec::with_capacity(num_words);
64+
for i in 0..num_words {
65+
let word = u32::from_le_bytes([
66+
bytes[4 * i],
67+
bytes[4 * i + 1],
68+
bytes[4 * i + 2],
69+
bytes[4 * i + 3],
70+
]);
71+
words.push(word);
72+
}
73+
words
74+
}
75+
76+
#[inline]
77+
/// Converts a slice of words to a byte vector in little endian.
78+
pub fn words_to_bytes_le_vec(words: &[u32]) -> Vec<u8> {
79+
words
80+
.iter()
81+
.flat_map(|word| word.to_le_bytes().into_iter())
82+
.collect::<Vec<_>>()
83+
}
84+
85+
#[inline]
86+
/// Converts a slice of words to a slice of bytes in little endian.
87+
pub fn words_to_bytes_le<const B: usize>(words: &[u32]) -> [u8; B] {
88+
debug_assert_eq!(words.len() * 4, B);
89+
let mut iter = words.iter().flat_map(|word| word.to_le_bytes().into_iter());
90+
core::array::from_fn(|_| iter.next().unwrap())
91+
}
92+
93+
#[inline]
94+
/// Converts a byte array in little endian to a slice of words.
95+
pub fn bytes_to_words_le<const W: usize>(bytes: &[u8]) -> [u32; W] {
96+
debug_assert_eq!(bytes.len(), W * 4);
97+
let mut iter = bytes
98+
.chunks_exact(4)
99+
.map(|chunk| u32::from_le_bytes(chunk.try_into().unwrap()));
100+
core::array::from_fn(|_| iter.next().unwrap())
101+
}
102+
103+
#[inline]
104+
/// Converts a byte array in little endian to a vector of words.
105+
pub fn bytes_to_words_le_vec(bytes: &[u8]) -> Vec<u32> {
106+
bytes
107+
.chunks_exact(4)
108+
.map(|chunk| u32::from_le_bytes(chunk.try_into().unwrap()))
109+
.collect::<Vec<_>>()
110+
}

0 commit comments

Comments
 (0)