Skip to content

Instantly share code, notes, and snippets.

@BartMassey
Created January 5, 2020 07:30
Show Gist options
  • Save BartMassey/ff0ea9e2396539023205d0595e19caad to your computer and use it in GitHub Desktop.
Save BartMassey/ff0ea9e2396539023205d0595e19caad to your computer and use it in GitHub Desktop.
Various conversions for U256 values, done properly with minimal tests
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub struct U256([u8; 32]);
impl Into<u8> for U256 {
fn into(self) -> u8 {
for b in &self.0[0..31] {
assert_eq!(*b, 0);
}
self.0[31]
}
}
impl From<usize> for U256 {
fn from(val: usize) -> U256 {
let mut value_array: [u8; 32] = [0; 32];
let value_bytes = val.to_be_bytes();
let offset = value_array.len() - value_bytes.len();
for (i, &v) in value_bytes.iter().enumerate() {
value_array[i + offset] = v;
}
U256(value_array)
}
}
impl Into<usize> for U256 {
fn into(self) -> usize {
let mut value_bytes = 0usize.to_be_bytes();
let offset = 32 - value_bytes.len();
for b in &self.0[0..offset] {
assert_eq!(*b, 0);
}
for (i, v) in value_bytes.iter_mut().enumerate() {
*v = self.0[i + offset];
}
usize::from_be_bytes(value_bytes)
}
}
#[test]
fn test_basic_conversions() {
let u256zero = U256([0; 32]);
let mut tmp = u256zero;
tmp.0[31] = 0xff_u8;
assert_eq!(0xff_u8, tmp.into());
/* XXX For now, we'll assume 64-bit usize. */
assert_eq!(8, std::mem::size_of::<usize>());
let mut tmp = u256zero;
let mut result = 0_usize;
for i in 24..32 {
tmp.0[i] = (i + 1) as u8;
result = (result << 8) | (i + 1);
}
assert_eq!(result, tmp.into());
assert_eq!(U256::from(result), tmp);
}
#[test]
#[should_panic]
fn test_into_u8_ovf() {
let mut u256big = U256([0x00; 32]);
u256big.0[30] = 0x01;
let _: u8 = u256big.into();
}
#[test]
#[should_panic]
fn test_into_usize_ovf() {
let mut u256big = U256([0x00; 32]);
/* XXX For now, we'll assume 64-bit usize or less. */
u256big.0[23] = 0x01;
let _: usize = u256big.into();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment