1use crate::constants::BITS_PER_LIMB;
2pub(crate) use crate::constants::Limb;
3
4#[derive(Debug, Copy, Clone)]
6pub(crate) struct LimbBitIndexPair {
7 pub(crate) limb: usize,
8 pub(crate) bit_index: usize,
9}
10
11pub(crate) fn from_bytes(limbs: &mut [Limb], data: &mut impl std::io::Read) -> std::io::Result<()> {
13 if cfg!(target_endian = "little") {
14 let num_bytes = std::mem::size_of_val(limbs);
15 let buf: &mut [u8] =
16 unsafe { std::slice::from_raw_parts_mut(limbs.as_mut_ptr() as *mut u8, num_bytes) };
17 data.read_exact(buf)
18 } else {
19 for entry in limbs {
20 let mut bytes: [u8; size_of::<Limb>()] = [0; size_of::<Limb>()];
21 data.read_exact(&mut bytes)?;
22 *entry = Limb::from_le_bytes(bytes);
23 }
24 Ok(())
25 }
26}
27
28pub(crate) fn to_bytes(limbs: &[Limb], data: &mut impl std::io::Write) -> std::io::Result<()> {
30 if cfg!(target_endian = "little") {
31 let num_bytes = std::mem::size_of_val(limbs);
32 let buf: &[u8] =
33 unsafe { std::slice::from_raw_parts(limbs.as_ptr() as *const u8, num_bytes) };
34 data.write_all(buf)
35 } else {
36 for limb in limbs {
37 let bytes = limb.to_le_bytes();
38 data.write_all(&bytes)?;
39 }
40 Ok(())
41 }
42}
43
44pub(crate) fn sign_rule(mut target: Limb, mut source: Limb) -> u32 {
45 let mut result = 0;
46 let mut n = 1;
47 while 2 * n < BITS_PER_LIMB {
49 let mask: Limb = !0 / ((1 << (2 * n)) - 1);
51 result ^= (mask & (source >> n) & target).count_ones() % 2;
52 source = source ^ (source >> n);
53 target = target ^ (target >> n);
54 n *= 2;
55 }
56 result ^= (1 & (source >> (BITS_PER_LIMB / 2)) & target) as u32;
57 result
58}