Serialization for cryptonums.

This commit is contained in:
2018-03-06 19:22:57 -08:00
parent f89e3e5ca4
commit f3d4b102c0
2 changed files with 52 additions and 2 deletions

View File

@@ -230,6 +230,42 @@ macro_rules! construct_unsigned {
generic_div(&self.contents, &a.contents, generic_div(&self.contents, &a.contents,
&mut q.contents, &mut r.contents); &mut q.contents, &mut r.contents);
} }
fn to_bytes(&self) -> Vec<u8> {
let mut res = Vec::with_capacity($count * 8);
for x in self.contents.iter() {
res.push( (x >> 56) as u8 );
res.push( (x >> 48) as u8 );
res.push( (x >> 40) as u8 );
res.push( (x >> 32) as u8 );
res.push( (x >> 24) as u8 );
res.push( (x >> 16) as u8 );
res.push( (x >> 8) as u8 );
res.push( (x >> 0) as u8 );
}
res
}
fn from_bytes(x: &[u8]) -> $type {
let mut res = $type::zero();
let mut i = 0;
assert!(x.len() >= ($count * 8));
for chunk in x.chunks(8) {
assert!(chunk.len() == 8);
res.contents[i] = ((chunk[0] as u64) << 56) |
((chunk[1] as u64) << 48) |
((chunk[2] as u64) << 40) |
((chunk[3] as u64) << 32) |
((chunk[4] as u64) << 24) |
((chunk[5] as u64) << 16) |
((chunk[6] as u64) << 8) |
((chunk[7] as u64) << 0);
i += 1;
}
assert!(i == $count);
res
}
} }
#[cfg(test)] #[cfg(test)]
@@ -638,6 +674,13 @@ macro_rules! construct_unsigned {
} }
} }
quickcheck! {
fn serialization_inverts(a: $type) -> bool {
let bytes = a.to_bytes();
let b = $type::from_bytes(&bytes);
a == b
}
}
} }
}; };
} }

View File

@@ -1,5 +1,12 @@
pub trait CryptoNum { pub trait CryptoNum {
/// Simultaneously compute the quotient and remainder of this number and
/// the given divisor.
fn divmod(&self, a: &Self, q: &mut Self, r: &mut Self); fn divmod(&self, a: &Self, q: &mut Self, r: &mut Self);
/// Convert a number to a series of bytes, in standard order (most to
/// least significant)
fn to_bytes(&self) -> Vec<u8>;
/// Convert a series of bytes into the number. The size of the given slice
/// must be greater than or equal to the size of the number, and must be
/// a multiple of 8 bytes long. Unused bytes should be ignored.
fn from_bytes(&[u8]) -> Self;
} }